实操玩家:

在苹果手机上,我们只要打开定位服务,拍照后便能在相簿中找到地图,地图上显示着在各地拍摄的相片。网站上这种显示方式也并不少见,例如 Flickr、即将关闭的 Panoramio 等。

作为地图爱好者,每每看到地图就激动不已,就想若能在自己博客上也这么显示,那该多好!

▲ 苹果手机上的相片地图

相片的地理位置信息,是通过手机等设备的 GPS 模块记录的,并在其图片文件的 EXIF 数据,保留了这些位置信息。

使用七牛做博客图床以来,其图片处理 API 为各种显示需求提供了便利,这其中有个可以获取图片 EXIF 信息的 API,可以很方便的获取到图片的 EXIF 信息,而 EXIF 包含的 GPS 位置信息,则可以实现以上所提到的效果。

实现流程

EXIF 为位置信息保留了经纬坐标、海拔等,将它转成实际地址信息,或者显示到地图上,还需要配合一个地图 API,在此就以高德地图为例。

实现流程大致如下

  • 请求数据:利用七牛 API 请求获取图片的 GPS 信息

  • 转换坐标:因相片的坐标数据是以 WGS84 坐标系统为准的,得转换坐标

  • 显示地址:通过高德地图 API 实现

获取坐标

我们还是以一张图片为例,来分析下如何实现。

▲ 莲阳河畔,渡亭堤顶的花

上图是在汕头市澄海区莲下镇渡亭村莲阳河畔拍的花,其图片地址如下:http://source.fooleap.org/show-photo-location-on-map-with-qiniu-and-amap-api.jpg

那么,七牛图片 EXIF 信息的接口如下:http://source.fooleap.org/show-photo-location-on-map-with-qiniu-and-amap-api.jpg?exif

直接用浏览器打开,可以很方便地找到所有 GPS 开头的属性。其中,海拔等数据可以忽略掉,位置信息最为重要的是经纬坐标,即以下四个值:

{
"GPSLatitude": {
"val": "23, 29, 10.91",
"type":
},
"GPSLatitudeRef": {
"val": "N",
"type":
},
"GPSLongitude": {
"val": "116, 46, 36.49",
"type":
},
"GPSLongitudeRef": {
"val": "E",
"type":
} }

那么这个坐标为 23°29’10.91”N, 116°46’36.49”E,也就是北纬 24 度 29 分 10.91 秒,东经 116 度 46 分 36.49 秒。

在各种互联网地图上,坐标是以度为单位的,东经北纬为正值,西经南纬为负值。这里需要将度分秒的经纬度转换以度为单位的,因度分秒之间为 60 进制,故转换公式为:

度分秒 = 度 + 分 /  + 秒 / ( * )

计算后得出上面的坐标约为 116.776803, 23.486364,这是一个 WGS84 坐标。

坐标转换此前已经说过不少了,因在网页上使用,直接采用 coordtransform 模块[3] 即可,以上坐标转换为 GCJ02 是 116.781381, 23.483788。

可以使用高德的坐标拾取系统,按坐标搜索一下,验证结果是否正确。

以上过程使用 JS 实现代码如下,需引入 coordtransform 模块。

var xhr = new XMLHttpRequest();

xhr.open('GET', 'http://source.fooleap.org/show-photo-location-on-map-with-qiniu-and-amap-api.jpg?exif', true);

xhr.onreadystatechange = function() {
if (xhr.readyState == && xhr.status == )
{
var data = JSON.parse(xhr.responseText);
if ( !!data.GPSLongitude ) {
var olat = data.GPSLatitude.val.split(', ');
var olng = data.GPSLongitude.val.split(', ');
var lat=, lng=, coord;
for( var i = ; i < olat.length; i++ ){
lat += olat[i] / Math.pow(, i);
lng += olng[i] / Math.pow(, i);
}
lat = data.GPSLatitudeRef.val == 'S' ? -lat: lat;
lng = data.GPSLongitudeRef.val == 'W' ? -lng: lng;
coord = coordtransform.wgs84togcj02(lng, lat).join(',');
}
} } xhr.send();

获取图片地址信息

有了坐标就有了地理位置,有了地理位置就知道是什么地方。高德地图逆地理编码 API 正在招手:「给我一个坐标,我将还你一个详细地址。」

根据文档,最基本的只需 location 参数传个坐标即可返回地址信息。此 API 还可批量获取,可以根据自己需求传入可选的参数。

以上面获取的坐标为例:

http://restapi.amap.com/v3/geocode/regeo?location=116.781381,23.48378&key=<用户的key>

请求后返回的 JSON 如下,具体返回的参数的详细说明参考文档。

{
"status": "",
"info": "OK",
"infocode": "",
"regeocode": {
"formatted_address": "广东省汕头市澄海区莲下镇渡亭村",
"addressComponent": {
"country": "中国",
"province": "广东省",
"city": "汕头市",
"citycode": "",
"district": "澄海区",
"adcode": "",
"township": "莲下镇",
"towncode": "",
"neighborhood": {
"name": [],
"type": []
},
"building": {
"name": [],
"type": []
},
"streetNumber": {
"street": "文明路",
"number": "159号",
"location": "116.78592,23.48872",
"direction": "东北",
"distance": "718.365"
},
"businessAreas": [
[]
]
}
} }

准确度一般般,到乡(镇、街道)这一级基本没问题。我们也不需要太准确的信息,毕竟定位信息有时候还是挺隐私的。

显示相片地图 

将相片显示在地图上,这似乎才是初衷,在这里,我将它分成两部分,一部分是静态地图,一部分是动态地图。

静态地图

将图片显示到静态地图上面,需要用到的高德地图 API 是静态地图 API。

根据高德的文档,自定义标注(marker)图片只能支持 PNG 格式,需要多来一张图片吗?不需要,这里可以直接用七牛图片处理 API,将原图调下大小并指定输出格式。

http://source.fooleap.org/show-photo-location-on-map-with-qiniu-and-amap-api.jpg?imageView2/1/w/100/h/100/format/png

上面的链接是输出等比缩放并居中裁剪的 100x100 PNG 格式图片,然而应用到高德接口还是出错了。我尝试在最后再加上 .png,结果成功,这意味着高德是以后缀名判断文件格式的,也是醉了。

http://restapi.amap.com/v3/staticmap?zoom=12&size=640*427&scale=2&markers=-1,http://source.fooleap.org/show-photo-location-on-map-with-qiniu-and-amap-api.jpg?imageView2/1/w/100/h/100/format/png.png,0:116.781381,23.48378&key=<用户的key>

以上拼凑出的链接显示如下。

▲ 高德静态地图 API 显示相片位置

高德静态地图 API 一样支持批量,具体可查看文档。

动态地图

想要在网页中实现跟苹果相册地图差不多样式且可控的地图,这就得用到高德地图 JS API,主要是用到点标记,这里就不多废话了,直接上图。


推荐阅读:

动手实操(一):如何用七牛云 API 实现相片地图?的更多相关文章

  1. 动手实操:如何用 Python 实现人脸识别,证明这个杨幂是那个杨幂?

    当前,人脸识别应用于许多领域,如支付宝的用户认证,许多的能识别人心情的 AI,也就是人的面部表情,还有能分析人的年龄等等,而这里面有着许多的难度,在这里我想要分享的是一个利用七牛 SDK 简单的实现人 ...

  2. 【PHP】Thinkphp 七牛云API对接

    访问一个网站,图片的流量占的比例是非常高的!在你的服务器硬盘上,图片占的容量也是非常高的. 如果要搞一个图片非常多,用户量又很庞大的网站,那么,得花多少钱烧在服务器上? 这种时候,当然要用第三方图片存 ...

  3. 2.动手实操Apache ZooKeeper

    Tips 做一个终身学习的人! 日拱一卒,功不唐捐. 在本节中,我们将讲解如何下载并安装Apache ZooKeeper,以便我们可以直接开始使用ZooKeeper. 本部分旨在通过提供详细的安装和使 ...

  4. 动手实操丨RC522射频卡模块与IC卡完成充值消费查询的技术实现思路

    摘要:一文手把手教你利用RC522射频卡模块与IC卡完成充值消费查询的技术实现思路. 本文分享自华为云社区<​​​​​​​​​​​​​​RC522射频卡模块与IC卡完成充值消费查询的技术实现思路 ...

  5. 二:动手实操SpringBoot-使用Spring Initializr创建项目

    使用 Spring Initializr 初始化 Spring Boot 项目 Spring Initializr 从本质上说就是一个Web应用程序,它能为你构建Spring Boot项目结构. 虽然 ...

  6. angular封装七牛云图片上传,解决同一页面多个上传按钮分别上传

    step1:引入文件 引入Plupload *该SDK上传功能集于Plupload插件封装,所以需要下载Plupload; plupload.dev.js 引入qiniu.js为了简便,当时直接从官网 ...

  7. Go语言实战 - 网站性能优化第一弹“七牛云存储”

    由于用户纷纷反应山坡网的打开速度比较慢,所以两天前我们决定把服务器从linode迁移到阿里云. 整个迁移过程非常平滑,基本上一个小时就完成了.而且阿里云的配套设施提供的也很不错,运行状态监控什么的都有 ...

  8. iOS 七牛云上传并获取图片----【客户端】

           最近做了七牛云存储的有关内容,涉及到与后台交互获取验证的token,无奈,后台自命清高,不与理会,没办法呀,于是自己搞呗.首先呢在在七牛上注册一个账号,然后呢添加一个存储空间这时候空间名 ...

  9. PHP使用七牛云存储之图片的上传、下载、303重定向教程,CI框架实例

    网上关于七牛云存储的教程除了官网上的API文档,其他的资料太少了.研究了下API之后,现在已经能实现图片的上传和下载及上传之后的重定向. http://blog.csdn.net/cqcre/arti ...

随机推荐

  1. 牛人cad二次开发网站(.net)

    http://through-the-interface.typepad.com/through_the_interface/autocad_net/ http://through-the-inter ...

  2. [ AHOI 2013 ] 作业 & [ BZOJ 3809 ] Gty的二逼妹子序列

    \(\\\) Description 给出一个长为 \(n\) 的数列 \(A\) 和 \(k\),多次询问: 对于一个区间 \([L_i,R_i]\),问区间内有多少个数在 \([a_i,b_i]\ ...

  3. 项目适配iOS9遇到的一些问题及解决办法 ,以及URL 白名单配置方法

    1.网络请求报错.升级Xcode 7.0发现网络访问失败.输出错误信息 The resource could not be loaded because the App Transport Secur ...

  4. H5拖拽事件的完整过程和语法

    <!DOCTYPE HTML> <html> <head> <style type="text/css"> #div1 { widt ...

  5. android开发中设置字体

    转自:http://segmentfault.com/q/1010000000494116 http://ryanhoo.github.io/blog/2014/05/05/android-bette ...

  6. Android(java)学习笔记172:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)

    1. 接口 接口可以隐藏代码内部的细节,只暴露程序员想暴露的方法 2. 利用上面的思想优化之前的案例:服务(service)之绑定服务调用服务里面的方法,如下: (1)这里MainActivity.j ...

  7. centos7 系统安全加固方案

    一.密码长度与有效期 默认配置: [root@i-1y3we23j ~]# cat /etc/login.defs |grep PASS_ |grep -v '#' PASS_MAX_DAYS PAS ...

  8. laravel homestead comoser install 报错

    项目部署的时候composer install报错 说那个依赖包没有安装成功需要回滚删除但是删除不了 解决: 要配置共享文件 注:使用 NFS 的话,需要安装 vagrant-winnfsd 插件.该 ...

  9. pagehelper 分页

    分页jar包: <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pa ...

  10. selelinum+PhantomJS 爬取拉钩网职位

    使用selenium+PhantomJS爬取拉钩网职位信息,保存在csv文件至本地磁盘 拉钩网的职位页面,点击下一页,职位信息加载,但是浏览器的url的不变,说明数据不是发送get请求得到的. 我们不 ...