微信公众平台开发(三)--位置信息的识别

位置识别这是实际应用经常应用的消息,特别是很多商家,通过了解用户位置,给用户提供特别的产品或是商场的推荐。其中用户可能发送两种类型的消息:

1.微信地理位置信息

2.路名、标志性建筑或是商场名称

1.微信地理位置消息

认识一下,微信地理位置消息,包含一些什么信息

 

<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1351776360</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<Location_X>23.134521</Location_X>
<Location_Y>113.358803</Location_Y>
<Scale>20</Scale>
<Label><![CDATA[位置信息]]></Label>
<MsgId>1234567890123456</MsgId>
</xml>

包含的主要信息有经度纬度和Label的位置。可以根据label中描述的位置信息,提供给用户对应的服务。也可根据用户的经度纬度信息,提供你最近的产品或是有地域性的产品。

首先根据微信的地理位置信息,定义WeChatLocationMessage类,并能把Xml转换为WeChatLocationMessage对象

 

public class WeChatLocationMessage {
    
private String toUserName;
    
private String fromUserName;
    
private String createTime;
    
private String msgType;
    
private String locationx;
    
private String localtiony;
    
private String scale;
    
private String label;
    
private String msgId;
    
    
public static WeChatLocationMessage getWeChatLocationMessage(String xml){
        XStream xstream 
= new XStream(new DomDriver());
        WeChatLocationMessage  message 
= null;
        xstream.alias(
"xml", WeChatLocationMessage.class);
        xstream.aliasField(
"ToUserName", WeChatLocationMessage.class"toUserName");
        xstream.aliasField(
"FromUserName", WeChatLocationMessage.class"fromUserName");
        xstream.aliasField(
"CreateTime", WeChatLocationMessage.class"createTime");
        xstream.aliasField(
"MsgType", WeChatLocationMessage.class"msgType");
        xstream.aliasField(
"Location_X", WeChatLocationMessage.class"locationx");
        xstream.aliasField(
"Location_Y", WeChatLocationMessage.class"localtiony");
        xstream.aliasField(
"Scale", WeChatLocationMessage.class"scale");
        xstream.aliasField(
"Label", WeChatLocationMessage.class"label");
        xstream.aliasField(
"MsgId", WeChatLocationMessage.class"msgId");
        message 
= (WeChatLocationMessage)xstream.fromXML(xml);
        
return message;
    }
//getter and setter
}
本文利用百度的地图API,查找最近的银行做为示例。

 

    public String getPalace(String query,String lat,String lng) throws ClientProtocolException, IOException{
        HttpClient httpClient 
= new DefaultHttpClient();
        String url 
= palceRequestUrl(query,lat,lng);
        logger.log(Level.INFO, url);
        HttpGet httpget 
= new HttpGet(url);
        ResponseHandler
<String> responseHandler = new BasicResponseHandler();
        String responseBody 
= httpClient.execute(httpget, responseHandler);
        logger.log(Level.INFO,
"baidu response:"+responseBody);
        
return responseBody;
    }
    
    
public String palceRequestUrl(String query,String lat,String lng) throws UnsupportedEncodingException {
        String url 
= WeChatConstant.BASEURL + "place/search?query=" + URLEncoder.encode(query,"UTF-8"+ "&key="
                
+ WeChatConstant.MAPKEY +"&location="+lat+","+lng +"&radius=2000"+"&output=" + WeChatConstant.OUTPUTFORMAT;
        
return url;
    }

输出的结果

<PlaceSearchResponse>
    
<status>OK</status>
    
<results>
        
<result>
            
<name>中国工商银行东长安街支行</name>
            
<location>
                
<lat>39.915891</lat>
                
<lng>116.41867</lng>
            
</location>
            
<address>东城区东长安街1号东方广场西三办公楼1楼</address>
            
<uid>a025683c73033c35a21de987</uid>
            
<detail_url>http://api.map.baidu.com/place/detail?uid=a025683c73033c35a21de987&amp;amp;output=html&amp;amp;source=placeapi
            </detail_url>
            
<tag>银行,王府井/东单</tag>

        
</result>
      
</results>
</PlaceSearchResponse>

 

接下来,把百度地图反映出来的最近位置信息,以图文消息的格式展示给微信用户

 

    public static String getWeChatReplyNewsMessageByBaiduPlace(List<BaiduPlaceResponse> placeList, double lat, double lng,String userName, int size){
        WeChatReplyNewsMessage newsMessage 
= new WeChatReplyNewsMessage();
        List
<Item> items = new ArrayList<Item>();
        StringBuffer strBuf 
= new StringBuffer();
        logger.log(Level.INFO,
"placeList count="+placeList.size());
        newsMessage.setItems(items);
        
if(placeList.size()>size){
            newsMessage.setArticleCount(size);
        }
        
else{
            newsMessage.setArticleCount(placeList.size());
        }
        logger.log(Level.INFO,
"article count="+newsMessage.getArticleCount());
        newsMessage.setCreateTime(
new Date().getTime()+"");
        newsMessage.setMsgType(
"news");
        newsMessage.setFuncFlag(
"0");
        newsMessage.setToUserName(userName);
        newsMessage.setFromUserName(WeChatConstant.FROMUSERNAME);
        
for(int i = 0;i <newsMessage.getArticleCount();i++){
            BaiduPlaceResponse place 
= placeList.get(i);
            Double distance 
= GeoUtil.DistanceOfTwoPoints(Double.valueOf(place.getLng()), Double.valueOf(place.getLat()), lng, lat, GaussSphere.Beijing54);
            Item item 
= new Item();
            item.setTitle(place.getName()
+"["+distance+"米]"+"\n"+place.getAddress()+"\n"+place.getTelephone());
            item.setPicUrl(
"");
            item.setUrl(place.getDetailUrl());
            item.setDescription(
"");
            items.add(item);
        }
        logger.log(Level.INFO,
"newMessage="+newsMessage.toString());
        strBuf 
= strBuf.append(getWeChatNewsMessage(newsMessage));
        
        
return strBuf.toString();
    }
    
    
public static String getWeChatNewsMessage(WeChatReplyNewsMessage newsMessage){
        XStream xstream 
= new XStream(new DomDriver());
        xstream.alias(
"xml", WeChatReplyNewsMessage.class);
        xstream.aliasField(
"ToUserName", WeChatReplyNewsMessage.class"toUserName");
        xstream.aliasField(
"FromUserName", WeChatReplyNewsMessage.class"fromUserName");
        xstream.aliasField(
"CreateTime", WeChatReplyNewsMessage.class"createTime");
        xstream.aliasField(
"MsgType", WeChatReplyNewsMessage.class"msgType");
        xstream.aliasField(
"ArticleCount", WeChatReplyNewsMessage.class"articleCount");
        xstream.aliasField(
"Content", WeChatReplyNewsMessage.class"content");
        xstream.aliasField(
"FuncFlag", WeChatReplyNewsMessage.class"funcFlag");
        xstream.aliasField(
"Articles", WeChatReplyNewsMessage.class"items");
        
        xstream.alias(
"item", Item.class);
        xstream.aliasField(
"Title", Item.class"title");
        xstream.aliasField(
"Description", Item.class"description");
        xstream.aliasField(
"PicUrl", Item.class"picUrl");
        xstream.aliasField(
"Url", Item.class"url");
        
        
return xstream.toXML(newsMessage);
    }

 

2.路名、标志性建筑或是商场名称

对路名、标志性建筑等信息,方法还是通过第三方地图信息,确定输入的位置信息的经度纬度。

本文使用百度地图API,确定所查找的位置的经度和纬度。

 

    public String getGeoCode(String query) throws ClientProtocolException, IOException{
        HttpClient httpClient 
= new DefaultHttpClient();
        String url 
= geoCodeRequestUrl(query);
        logger.log(Level.INFO, url);
        HttpGet httpget 
= new HttpGet(url);
        ResponseHandler
<String> responseHandler = new BasicResponseHandler();
        String responseBody 
= httpClient.execute(httpget, responseHandler);
        logger.log(Level.INFO,
"baidu response:"+responseBody);
        
return responseBody;
    }
    
    
public String geoCodeRequestUrl(String query) throws UnsupportedEncodingException{
        String url 
= WeChatConstant.BASEURL + "geocoder?address=" + URLEncoder.encode(query,"UTF-8"+ "&key="
                
+ WeChatConstant.MAPKEY + "&output=" + WeChatConstant.OUTPUTFORMAT;
        
return url;
    }

 

确定了经度和纬度,问题就变成和第1种消息类型一致了,根据经度纬度去做相应处理。

3.源代码

本文的代码较长,提供源代码下载。

WeChatDemo下载

 

原创文章,转载请注明: 转载自http://www.qiyadeng.com/

本文链接地址: 微信公众平台开发(三)–位置信息的识别










posted @ 2013-03-25 21:43  qiyadeng  阅读(2678)  评论(4编辑  收藏  举报
ga('create', 'UA-39683036-1', 'cnblogs.com'); ga('send', 'pageview');