前言

有没有发现咱们国内的卫星地图放大到一定程度就”糊”了?想看看自家位置?不好意思,看不清…

别慌:用 Cloudflare Workers(免费的!)反代 Google Map,然后导入奥维互动地图,轻轻松松看高清卫星图!

为什么想用 Google 卫星图?

原因很简单:

  1. 境内卫图太糊:放大后就一片模糊,细节啥的根本看不到
  2. Google 卫星图不错:但问题是被限制了,直接访问不了

所以咱们今天的目标就是:用反代绕过这个限制,让奥维互动地图能加载 Google 的高清卫星图

一、先把家伙准备好

工欲善其事,必先利其器。咱们需要这几样东西:

  • 奥维互动地图:没安装的话去官网下一个,这个软件挺不错的,支持多种地图源
  • 一个 Cloudflare 账号:免费的!每天 10 万次调用额度,够用了
  • 一个自己的域名:这个必须有!不然 workers.dev 在国内用不了

注意:Cloudflare Workers 的 *.workers.dev 域名在国内已经被 DNS 污染了,必须使用自定义域名才能正常访问。

二、创建 Cloudflare Workers

1. 注册 Cloudflare 账号

  1. 打开 Cloudflare 注册页面
  2. 用邮箱注册,选免费计划就行

2. 创建 Worker(网页操作)

  1. 进入 Cloudflare 控制台
  2. 点左侧菜单的 计算Workers & Pages
  3. 创建应用程序
  4. 选择 从 Hello World 开始
  5. 部署
  6. 部署完成后点 编辑代码,把反代代码复制进去(后面会讲)

3. 绑定自定义域名(必须!)

前置条件:你的域名需要先托管到 Cloudflare。

  1. 进入 Cloudflare 控制台,点击左侧 网站
  2. 添加站点,按提示把你的域名托管到 Cloudflare
  3. 在你的域名服务商那里,按照 Cloudflare 给出的 NS 服务器地址修改域名的 DNS 服务器

开始绑定域名到 Worker

  1. 域名托管完成后,点左侧菜单的 计算Workers & Pages
  2. 点击你刚创建的 Worker
  3. 设置域和路由自定义域
  4. 添加自定义域
  5. 填入你的域名,比如 map.yourdomain.com
  6. 等待 DNS 生效(约几分钟到几小时)

三、部署反代代码

1. 替换代码

用下面这个反代代码替换刚才创建 Worker 时的默认代码(即「二、创建 Cloudflare Workers」中第 2 步第 6 点打开的编辑器里的内容):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
const upstream = 'mt1.google.com'
const blocked_ip_address = ['0.0.0.0', '127.0.0.1']
const replace_dict = {
'$upstream': '$custom_domain',
'//mt1.google.com': ''
}
addEventListener('fetch', event =>{
event.respondWith(fetchAndApply(event.request));
})
async function fetchAndApply(request) {
const ip_address = request.headers.get('cf-connecting-ip');
const user_agent = request.headers.get('user-agent');
let response = null;
let url = new URL(request.url);
let url_host = url.host;
if (url.protocol == 'http:') {
url.protocol = 'https:'
response = Response.redirect(url.href);
return response;
}
url.host = upstream;
if (blocked_ip_address.includes(ip_address)) {
response = new Response('Access denied: Your IP address is blocked by WorkersProxy.', {
status: 403
});
} else {
let method = request.method;
let request_headers = request.headers;
let new_request_headers = new Headers(request_headers);
new_request_headers.set('Host', upstream);
new_request_headers.set('Referer', url.href);
let original_response = await fetch(url.href, {
method: method,
headers: new_request_headers
})
let original_response_clone = original_response.clone();
let original_text = null;
let response_headers = original_response.headers;
let new_response_headers = new Headers(response_headers);
let status = original_response.status;
new_response_headers.set('access-control-allow-origin', '*');
new_response_headers.set('access-control-allow-credentials', true);
new_response_headers.delete('content-security-policy');
new_response_headers.delete('content-security-policy-report-only');
new_response_headers.delete('clear-site-data');
const content_type = new_response_headers.get('content-type');
if (content_type.includes('text/html') && content_type.includes('UTF-8')) {
original_text = await replace_response_text(original_response_clone, upstream, url_host);
} else {
original_text = original_response_clone.body
}
response = new Response(original_text, {
status,
headers: new_response_headers
})
}
return response;
}
async function replace_response_text(response, upstream, host_name) {
let text = await response.text()
var i, j;
for (i in replace_dict) {
j = replace_dict[i]
if (i == '$upstream') {
i = upstream
} else if (i == '$custom_domain') {
i = host_name
}
if (j == '$upstream') {
j = upstream
} else if (j == '$custom_domain') {
j = host_name
}
let re = new RegExp(i, 'g')
text = text.replace(re, j);
}
return text;
}
async function device_status(user_agent_info) {
var agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (var v = 0; v < agents.length; v++) { if (user_agent_info.indexOf(agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}

部署成功后,你的反代地址就是你绑定的自定义域名,比如 https://map.yourdomain.com

四、在奥维互动地图里配置

这是重头戏!打开奥维互动地图,按以下步骤操作:

1. 添加自定义地图

  1. 点击左上角 菜单系统设置
  2. 找到 地图设置自定义地图
  3. 点击 添加

2. 填写配置信息

按照下表填写(注意把域名改成你自己的):

配置项 填什么
地图名称 Google卫星图(反代)
协议 https
主机名 你的自定义域名,比如 map.yourdomain.com
端口号 443
最大级别 20
投影类型 墨卡托中国
图片格式 PNG
图片大小 256像素
图片类型 影像地图

3. URL 模板

奥维支持的 Google 地图 URL 有好几种,根据自己需求选:

地图类型 URL 模板 说明
卫星影像图 /vt/lyrs=s@699&hl=zh-CN&gl=cn&src=app&x={$x}&y={$y}&z={$z}&s= 纯卫星影像,无路网
卫星+路网 /vt/lyrs=s,m@699&hl=zh-CN&gl=cn&src=app&x={$x}&y={$y}&z={$z}&s= 影像+路网叠加
路网小字体 /vt/imgtp=png32&lyrs=h@292000000&hl=zh-CN&gl=cn&x={$x}&y={$y}&z={$z}&s=Galileo 只有路网,256px
路网大字体 /vt/imgtp=png32&lyrs=h@292000000&hl=zh-CN&gl=cn&x={$x/2}&y={$y/2}&z={$z-1}&scale=2&s=Galileo 只有路网,512px

注意:最常用的是 卫星影像图,如果想要路网叠加效果,可以单独再添加一个路网图层叠加上去。

4. 测试加载

添加完之后,回到主界面,在地图切换里找到咱们刚加的 “Google卫星图(反代)”,切换过去看看能不能正常显示。

5. 叠加路网(可选)

如果觉得纯卫星图不方便认路,可以再添加一个路网图层:

  1. 再次点击 添加,新建一个自定义地图
  2. 地图名称填 Google路网
  3. URL 模板选择上表的 路网小字体
  4. 配置好后,在奥维里可以同时显示卫星图+路网,或者切换叠加模式

6. 如何验证反代是否正常工作?

在浏览器里访问以下地址测试(把域名换成你自己的):

1
https://map.yourdomain.com/vt/lyrs=s@699&hl=zh-CN&gl=cn&src=app&x=1&y=1&z=1

如果返回图片,说明反代工作正常。

五、搞定!

通过 Cloudflare Workers 反向代理这个免费方案,咱们终于能在国内愉快地看 Google 高清卫星图了!