用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 相关文章推荐
PHPStorm 2020.1 调试 Nodejs的多种方法详解
Sep 17 NodeJs
Nodejs中自定义事件实例
Jun 20 NodeJs
nodejs中使用monk访问mongodb
Jul 06 NodeJs
Nodejs Stream 数据流使用手册
Apr 17 NodeJs
Nodejs进阶:核心模块net入门学习与实例讲解
Nov 21 NodeJs
nodejs实例解析(输出hello world)
Jan 03 NodeJs
理解nodejs的stream和pipe机制的原理和实现
Aug 12 NodeJs
nodejs微信扫码支付功能实现
Feb 17 NodeJs
nodejs取得当前执行路径的方法
May 13 NodeJs
纯异步nodejs文件夹(目录)复制功能
Sep 03 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 NodeJs
NodeJS有难度的面试题(能答对几个)
Oct 09 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中empty is_null和isset的测试
2013/06/29 PHP
JS异常处理try..catch语句的作用和实例
2014/05/05 PHP
php 防止表单重复提交两种实现方法
2016/11/03 PHP
thinkPHP自定义类实现方法详解
2016/11/30 PHP
PHP PDOStatement::execute讲解
2019/01/31 PHP
thinkPHP框架RBAC实现原理分析
2019/02/01 PHP
详解提高使用Java反射的效率方法
2019/04/29 PHP
解决laravel查询构造器中的别名问题
2019/10/17 PHP
TimergliderJS 一个基于jQuery的时间轴插件
2011/12/07 Javascript
javascript实现图片切换的幻灯片效果源代码
2012/12/12 Javascript
js一般方法改写成面向对象方法的无限级折叠菜单示例代码
2013/07/04 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
JS如何将数字类型转化为没3个一个逗号的金钱格式
2014/01/27 Javascript
JavaScript+html5 canvas绘制渐变区域完整实例
2016/01/26 Javascript
小白谈谈对JS原型链的理解
2016/05/03 Javascript
jquery实现下拉框功能效果【实例代码】
2016/05/06 Javascript
基于jquery插件编写countdown计时器
2016/06/12 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
HTML5canvas 绘制一个圆环形的进度表示实例
2016/12/16 Javascript
JQuery用$.ajax或$.getJSON跨域获取JSON数据的实现代码
2017/09/23 jQuery
js canvas实现红包照片效果
2018/08/21 Javascript
Vue 报错TypeError: this.$set is not a function 的解决方法
2018/12/17 Javascript
微信小程序实现swiper切换卡内嵌滚动条不显示的方法示例
2018/12/20 Javascript
使用Promise封装小程序wx.request的实现方法
2019/11/13 Javascript
举例介绍Python中的25个隐藏特性
2015/03/30 Python
python使用calendar输出指定年份全年日历的方法
2015/04/04 Python
python输入错误密码用户锁定实现方法
2017/11/27 Python
django认证系统 Authentication使用详解
2019/07/22 Python
美国家喻户晓的保健品品牌:Vitamin World(维他命世界)
2016/08/19 全球购物
求职自荐信格式
2013/12/04 职场文书
学校招生宣传广告词
2014/03/19 职场文书
节约能源标语
2014/06/17 职场文书
区政府领导班子个人对照检查材料
2014/09/25 职场文书
投诉信回复范文
2015/07/03 职场文书
告诉你一个秘密:富人致富的五大优点
2019/07/11 职场文书
tomcat正常启动但网页却无法访问的几种解决方法
2022/05/06 Servers