用NodeJS实现批量查询地理位置的经纬度接口


Posted in NodeJs onAugust 16, 2016

实现步骤

1、 查询接口

网站上这种类型的接口还不少,笔者直接找了百度地图的接口做,接口文档,调用的API是Geocoding API中的地理编码服务

请求示例:对北京市百度大厦进行地理编码查询

http://api.map.baidu.com/geocoder/v2/?ak=E4805d16520de693a3fe707cdc962045&callback=renderOption&output=json&address=百度大厦&city=北京市

这里面需要一个ak参数,这个参数就是用户创建应用时生成的一串字符串,需要在请求数据的时候调用。

[注意]

创建的应用为服务端类型

创建应用有两种校验方式供选择,你可以选择使用IP白名单校验,也可以选择使用sn做校验,两者不同点在于IP需要提前设定好你请求时候的IP地址,如果你不想提前设定死IP地址,也可以选择sn校验,这是利用md5作为加密算法的校验方式。
笔者一开始选择sn做校验,但是调用crypto生成md5签名一直校验不过,只能改用ip白名单作为校验

2、nodejs进行查询

有了供调用的接口,我们就可以写个小脚本去请求数据,我们需要三个依赖,分别是express、superagent、eventproxy
express是一个轻量级的web应用

superagent是一个爬虫经常用的库,可以模拟各种请求

eventproxy是一个并发控制器

* 简单查询

首先我们先写一个简单的请求来检测是否能获取到地理位置:

app.get('/one', function(req, res, next) {
  
  var sk = 'yoursk' // 创建应用的sk
    , address = '北京市'
    ;
  superagent.get('http://api.map.baidu.com/geocoder/v2/')
    .query({address: address})
    .query({output: 'json'})
    .query({ak: sk})
    .end(function(err, sres) {
      if (err) {
        console.log('err:', err);
        return;
      }
      res.send(sres.text);
    }) 
 })

然后打开浏览器访问:http://localhost:8888/one

{
  status: 0,
  result: {
  location: {
    lng: 116.39564503787867,
    lat: 39.92998577808024
  },
  precise: 0,
  confidence: 10,
  level: "城市"
}

当你能看到这些信息的时候 ,说明接口成功了,如果status不为0的时候,请参考返回码状态表

为什么要专门开个服务器才能去请求呢,因为我们创建的应用是服务端,我们需要建一个服务器才能去请求。

* 批量查询

好了,一个城市可以查询了,接下来我们要进行多个城市的查询,我们使用eventproxy做并发控制,你可以把它看做一个计数器,你可以命令它监听某个事件,并在n次后执行对应的函数。

关键代码如下:

app.get('/many', function(req, res, next) {
  var sk = 'yoursk'
    , addresses = ['北京市', '深圳市', '广州市', '普宁市']
    ;
  ep.after('getLocation', addresses.length, function(locations) {
    res.send(locations);
  })
  addresses.forEach(function(e, i) {
    superagent.get('http://api.map.baidu.com/geocoder/v2/')
      .query({address: e})
      .query({output: 'json'})
      .query({ak: sk})
      .end(function(err, sres) {
        ep.emit('getLocation', {address: e, res: sres.text})
      })  
  })
})

打开浏览器访问:http://localhost:8888/many

[
{
address: "北京市",
res: "{"status":0,"result":{"location":{"lng":116.39564503787867,"lat":39.92998577808024},"precise":0,"confidence":10,"level":"城市"}}"
},
{
address: "深圳市",
res: "{"status":0,"result":{"location":{"lng":114.0259736573215,"lat":22.546053546205248},"precise":0,"confidence":14,"level":"城市"}}"
},
{
address: "广州市",
res: "{"status":0,"result":{"location":{"lng":113.30764967515182,"lat":23.12004910207623},"precise":0,"confidence":12,"level":"城市"}}"
},
{
address: "普宁市",
res: "{"status":0,"result":{"location":{"lng":116.07816590835329,"lat":23.28895358314155},"precise":0,"confidence":14,"level":"区县"}}"
}
]

好了,批量查询也没有问题了,接下来我们要用nodejs去读取后台工程师丢给我的excel文件

3、nodejs读写文件

这次我们需要多两个依赖,一个nodejs内置的fs模块,一个用来读写excel的库node-xlsx

将要城市的excel文件丢到根目录下,另起一个脚本xls2js.js:

var xlsx = require('node-xlsx')
  , fs = require('fs')
  ;
var file_path = './query_result.xlsx';
var file_data = xlsx.parse(file_path);

再调用fs.writeFile将提取出来的城市写入,代码如下:

file_data.forEach(function(sheet, index) {
  var sheetname = sheet.name // 表格名称
    , sheetdata = sheet.data // 表格的数据
    , sheethead = sheetdata[0] // 第一行一般为表头,但不是一定的
    , sheetbody = sheetdata.slice(1) // 真正的数据
    , file_path_towrite = './static/address.json'
    , file_data_json
    , cities_name = []
    ;
  // 将城市的数据写进去
  sheetbody.forEach(function(e, i) {
    cities_name.push('' + e[1] + ',' + e[2])
  })
  file_data_json = JSON.stringify({cities_name: cities_name});
  fs.writeFile(file_path_towrite, file_data_json, function(err) {
    if (err) 
      console.log('写入数据失败', err);
    else 
      console.log('写入文件成功');
  })
})

打开static/address.json文件,会看到如下格式的文本:

{"cities_name":["北京市,北京市","北京市,市辖区","天津市,天津市"]}

4、综合步骤2、3实现一个读取本地城市文件、批量查询、写入新的文件的接口

好了,有了这个文件,我们就可以再次读取然后进行批量查询:

app.get('/', function(req, res, next) {
  var sk = 'yoursk'
    , addresses = []
    , file_path = './static/address.json'
    , file_path_towrite = './static/geocoder.json'
    , file_data
    ;

  fs.readFile(file_path, function(err, data) {
    if (err) {
      console.log('读取文件失败', err);
      return;
    }
    file_data = JSON.parse(data);
    addresses = file_data.cities_name;
    
    ep.after('getLocation', addresses.length, function(locations) {
      var file_data = {};
      locations.forEach(function(e, i) {
        file_data[e.address.split(',')[1]] = [e['location']['lng'], e['location']['lat']];
      })
      fs.writeFile(file_path_towrite, JSON.stringify(file_data), function(err) {
        if (err) 
          console.log('写入数据失败', err);
        else 
          console.log('获取数据并写入文件成功');
        res.send(file_data);
      })
    })
    addresses.forEach(function(e, i) {
      superagent.get('http://api.map.baidu.com/geocoder/v2/')
        .query({address: e.split(',').join(' ')})
        .query({city: e.split(',')[1]})
        .query({output: 'json'})
        .query({ak: sk})
        .end(function(err, sres) {
          var location
            , res_json
            ;
          res_json = JSON.parse(sres.text);
          if (res_json.status == 0) {
            location = res_json.result && res_json.result.location || '';
          } else {
            location = {"lng":0,"lat":0};
          }
          ep.emit('getLocation', {address: e, location: location})
        })
    })
  });
})

5、实现一个网页,可以进行输入地理位置来进行地理位置的批量查询

这些就是前端的事情了,怎么好看怎么写

6、总结

以上就是用NodeJS实现批量查询地理位置的经纬度接口的全部内容,希望对大家使用nodejs能有所帮助。

NodeJs 相关文章推荐
NodeJS框架Express的模板视图机制分析
Jul 19 NodeJs
Nodejs抓取html页面内容(推荐)
Aug 11 NodeJs
Nodejs 搭建简单的Web服务器详解及实例
Nov 30 NodeJs
图片上传之FileAPI与NodeJs
Jan 24 NodeJs
详解nodejs中exports和module.exports的区别
Feb 17 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
Windows下使用Nodejs运行js的方法
Sep 02 NodeJs
NodeJs搭建本地服务器之使用手机访问的实例讲解
May 12 NodeJs
Nodejs封装类似express框架的路由实例详解
Jan 05 NodeJs
基于NodeJS开发钉钉回调接口实现AES-CBC加解密
Aug 20 NodeJs
分享node.js实现简单登录注册的具体代码
Apr 26 NodeJs
使用nodejs中httpProxy代理时候出现404异常的解决方法
Aug 15 #NodeJs
NodeJs的优势和适合开发的程序
Aug 14 #NodeJs
在windows上用nodejs搭建静态文件服务器的简单方法
Aug 11 #NodeJs
Nodejs抓取html页面内容(推荐)
Aug 11 #NodeJs
用nodejs的实现原理和搭建服务器(动态)
Aug 10 #NodeJs
nodejs如何获取时间戳与时间差
Aug 03 #NodeJs
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
Jul 26 #NodeJs
You might like
php分页函数
2006/07/08 PHP
PHP CURL CURLOPT参数说明(curl_setopt)
2013/09/30 PHP
PHP实现的权重算法示例【可用于游戏根据权限来随机物品】
2019/02/15 PHP
能说明你的Javascript技术很烂的五个原因分析
2011/10/28 Javascript
解决Extjs 4 Panel作为Window组件的子组件时出现双重边框问题
2013/01/11 Javascript
jquery 简单应用示例总结
2013/08/09 Javascript
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
js获取及判断键盘按键的方法
2015/12/01 Javascript
JS获取元素多层嵌套思路详解
2016/05/16 Javascript
JavaScript进阶练习及简单实例分析
2016/06/03 Javascript
浅谈JS的基础类型与引用类型
2016/09/13 Javascript
使用jQuery的ajax方法向服务器发出get和post请求的方法
2017/01/13 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
jQuery设计思想
2017/03/07 Javascript
从零开始学习Node.js系列教程之基于connect和express框架的多页面实现数学运算示例
2017/04/13 Javascript
基于BootStrap的前端分页带省略号和上下页效果
2017/05/18 Javascript
前端页面文件拖拽上传模块js代码示例
2017/05/19 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
2017/12/20 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
2018/08/06 Javascript
Vue表情输入组件 微信face表情组件
2019/02/11 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
ES6中的class是如何实现的(附Babel编译的ES5代码详解)
2019/05/17 Javascript
layer.alert回调函数执行关闭弹窗的实例
2019/09/11 Javascript
如何基于js判断浏览器版本
2020/02/20 Javascript
vue在线动态切换主题色方案
2020/03/26 Javascript
webstorm建立vue-cli脚手架的傻瓜式教程
2020/09/22 Javascript
如何在vue-cli中使用css-loader实现css module
2021/01/07 Vue.js
Python实现的北京积分落户数据分析示例
2020/03/27 Python
python IDLE添加行号显示教程
2020/04/25 Python
Jmeter调用Python脚本实现参数互相传递的实现
2021/01/22 Python
以设计师精品品质提供快速时尚:PopJulia
2018/01/09 全球购物
创业计划书如何编写
2014/02/06 职场文书
化学教育专业自荐信
2014/07/04 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
钓鱼岛事件感想
2015/08/11 职场文书
用人单位的规章制度,怎样制定才是有效的?
2019/07/09 职场文书