判断GPS坐标是否在中国

  由于 某些原因 ,国内地图总会有些偏移。虽说这是个相对偏移,但总会对需要坐标定位的应用造成几百米的漂移。若定位坐标在国外,则不会存在此问题。因此我们需要判别当前坐标是否在国内,然后决定是否进行坐标修正。

      判定坐标是否在国内,有下列几种方法可选:

  1. 通过网络地图接口查询
  2. 根据国家行政边界判定
  3. 根据国家行政边界近似判定

 

方法1,通过网络地图接口查询

      网络接口:http://maps.google.com/maps/api/geocode/xml?latlng=xxx,xxx&sensor=false,其中latlng参数填写的是坐标的经纬度参数。

      例如进行如下调用:http://maps.google.com/maps/api/geocode/xml?latlng=39.829632,117.059326&sensor=false

      返回结果如下:

<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
 <status>OK</status>
 <result>
  <type>route</type>
  <formatted_address>274 Provincial Rd, Sanhe, Langfang, Hebei, China</formatted_address>
  <address_component>
   <long_name>274 Provincial Rd</long_name>
   <short_name>S274</short_name>
   <type>route</type>
  </address_component>
  <address_component>
   <long_name>Sanhe</long_name>
   <short_name>Sanhe</short_name>
   <type>sublocality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Langfang</long_name>
   <short_name>Langfang</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Hebei</long_name>
   <short_name>Hebei</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>China</long_name>
   <short_name>CN</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <geometry>
   <location>
    <lat>39.8483120</lat>
    <lng>117.0741900</lng>
   </location>
   <location_type>APPROXIMATE</location_type>
   <viewport>
    <southwest>
     <lat>39.8292258</lat>
     <lng>117.0728091</lng>
    </southwest>
    <northeast>
     <lat>39.8674069</lat>
     <lng>117.0757736</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>39.8292258</lat>
     <lng>117.0728091</lng>
    </southwest>
    <northeast>
     <lat>39.8674069</lat>
     <lng>117.0757736</lng>
    </northeast>
   </bounds>
  </geometry>
 </result>
 <result>
  <type>sublocality</type>
  <type>political</type>
  <formatted_address>Sanhe, Langfang, Hebei, China</formatted_address>
  <address_component>
   <long_name>Sanhe</long_name>
   <short_name>Sanhe</short_name>
   <type>sublocality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Langfang</long_name>
   <short_name>Langfang</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Hebei</long_name>
   <short_name>Hebei</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>China</long_name>
   <short_name>CN</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <geometry>
   <location>
    <lat>39.9827180</lat>
    <lng>117.0782950</lng>
   </location>
   <location_type>APPROXIMATE</location_type>
   <viewport>
    <southwest>
     <lat>39.8081545</lat>
     <lng>116.7572022</lng>
    </southwest>
    <northeast>
     <lat>40.0850111</lat>
     <lng>117.2599867</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>39.8081545</lat>
     <lng>116.7572022</lng>
    </southwest>
    <northeast>
     <lat>40.0850111</lat>
     <lng>117.2599867</lng>
    </northeast>
   </bounds>
  </geometry>
 </result>
 <result>
  <type>locality</type>
  <type>political</type>
  <formatted_address>Langfang, Hebei, China</formatted_address>
  <address_component>
   <long_name>Langfang</long_name>
   <short_name>Langfang</short_name>
   <type>locality</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>Hebei</long_name>
   <short_name>Hebei</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>China</long_name>
   <short_name>CN</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <geometry>
   <location>
    <lat>39.5380470</lat>
    <lng>116.6837520</lng>
   </location>
   <location_type>APPROXIMATE</location_type>
   <viewport>
    <southwest>
     <lat>39.4355307</lat>
     <lng>116.5841675</lng>
    </southwest>
    <northeast>
     <lat>39.6029123</lat>
     <lng>116.8444061</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>38.4703170</lat>
     <lng>116.1166769</lng>
    </southwest>
    <northeast>
     <lat>40.0850111</lat>
     <lng>117.2599867</lng>
    </northeast>
   </bounds>
  </geometry>
 </result>
 <result>
  <type>administrative_area_level_1</type>
  <type>political</type>
  <formatted_address>Hebei, China</formatted_address>
  <address_component>
   <long_name>Hebei</long_name>
   <short_name>Hebei</short_name>
   <type>administrative_area_level_1</type>
   <type>political</type>
  </address_component>
  <address_component>
   <long_name>China</long_name>
   <short_name>CN</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <geometry>
   <location>
    <lat>38.0370570</lat>
    <lng>114.4686650</lng>
   </location>
   <location_type>APPROXIMATE</location_type>
   <viewport>
    <southwest>
     <lat>36.0482067</lat>
     <lng>113.4653687</lng>
    </southwest>
    <northeast>
     <lat>42.6197178</lat>
     <lng>119.8542560</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>36.0482067</lat>
     <lng>113.4653687</lng>
    </southwest>
    <northeast>
     <lat>42.6197178</lat>
     <lng>119.8542560</lng>
    </northeast>
   </bounds>
  </geometry>
 </result>
 <result>
  <type>country</type>
  <type>political</type>
  <formatted_address>China</formatted_address>
  <address_component>
   <long_name>China</long_name>
   <short_name>CN</short_name>
   <type>country</type>
   <type>political</type>
  </address_component>
  <geometry>
   <location>
    <lat>35.8616600</lat>
    <lng>104.1953970</lng>
   </location>
   <location_type>APPROXIMATE</location_type>
   <viewport>
    <southwest>
     <lat>18.1535216</lat>
     <lng>73.4994137</lng>
    </southwest>
    <northeast>
     <lat>53.5609740</lat>
     <lng>134.7728100</lng>
    </northeast>
   </viewport>
   <bounds>
    <southwest>
     <lat>18.1535216</lat>
     <lng>73.4994137</lng>
    </southwest>
    <northeast>
     <lat>53.5609740</lat>
     <lng>134.7728100</lng>
    </northeast>
   </bounds>
  </geometry>
 </result>
</GeocodeResponse>


      查询结果各字段的含义可以参考Google Map API的Reverse Geocoding (Address Lookup)章节。简化后可以直接判断返回的字符串中是否存在“<short_name>CN</short_name>”作为判定所查询坐标是否在中国的依据。

 

方法2,根据国家行政边界判定

      由于国家行政边界是由多个简单多边形组成的。对多个多边形进行命中测试 (Hit Testing),只要其中一个多边形测试成功,则表示整个命中测试成功。但多边形的命中测试有些麻烦,更简单的方法是判别点是否在多边形内(Point in polygon(PIP))。这些算法中简单高效的莫过于是光线投射算法 (Ray casting algorithm)

      光线投射算法的要义是:在二维空间的任意一点射出一条射线,射线穿过多边形边界奇数次则这个点在多边形内,否则在多边形外。此方法适用于复杂多边形。实现此算法往往会限制射线的方向是向右的,这样的好处是简化了许多计算。此算法的一个实现参考1987年Paul Bourke教授所写“Determining if a point lies on the interior of a polygon”的Solution 1。

      在 Windows Phone 7 中的实现,首先需要获取到国家行政边界的WGS84坐标数据。Alexey Strakh(链接有恶意软件警告)所开发的gMaps应用中包含了此边界数据。因此,自己可以把数据抠出来。抠出的数据由四部分组成我国的行政边界:大陆、台湾省、海南省、崇明岛。此数据相对来说比较准确,但是边界附近误差较大。每次判别坐标是否在此区域内的计算次数较多,大约需要几百次的几何计算。

      此方法的实现代码如下:

方法3,根据国家行政边界近似判定

      有时候需要一种快速的方法判定,这种快速判定的方法是从Nokia Maps中挖掘出来的。基本思路是:把整个行政区域划分为几个小的矩形,然后再排除掉一些矩形区域。只要一个点在限定的区域内,并且不在排除的区域内,则判定成功,否则失败。下图中蓝色区域为限定区域,红色区域为排除区域。

此方法的实现代码如下:

      这几种方法的比较

 备注
方法1 
通过网络地图接口查询
简单、准确 
信息量大
速度慢 
依赖网络
可用Google、Baidu地图接口
方法2 
根据国家行政边界判定
准确代码相对较多 
判别计算次数较多 
陆地边界数据误差较大
方法和数据从gMaps中挖掘
方法3 
根据国家行政边界近似判定
快速 
相对准确
边界误差较大方法和数据从Nokia Maps中挖掘

 

PS:你可能会问,在方法3中为什么把台湾给排除掉了,这是因为所谓的坐标偏移对台湾地区不适用。对于香港澳门地区,视情况需要单独判定。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值