文档章节

基于地理区域的广告推送模块

别寒
 别寒
发布于 2015/07/30 18:06
字数 1595
阅读 1015
收藏 58

近期遇到一个奇怪的需求,行车记录仪的后台需要可以根据地理区域对用户推送广告信息。这里的地理区域不同于市、省的划分,而是广告发布者在地图上选择的任意区域(中国境内),这意味着我们可以向大到城市、小到一个洗车行、停车场、快餐店等等小企业出租广告,并且可以根据用户选择的区域大小、区域竞争(比如商家买断某块区域中同类广告的投放权)进行阶梯收费。

 

功能描述:

商家或管理员在广告投放页面中选择任意形状的地理区域,当用户进入此广告区域时,商家投放的广告将通过后台服务器推送给用户。


功能难点:

1.在页面中模拟用户选择区域范围

2.如何判断GPS中的经纬度是否在地图上的广告区域中

 

实现过程:

1.使用百度地图完成该功能

2.在广告投放页面中使用百度地图完成区域选择和获取地理位置点

3.将用户选择的区域地理位置点上传到后台并保存至数据库中

3.结合行车记录仪每3分钟上传一次行车轨迹,取轨迹记录中的一个经纬度

4.将轨迹记录的经纬度和数据库中的区域位置点进行比较,判断该经纬度是否在区域中

5.如果在广告区域中,服务器将广告信息推送给行车记录仪

 

实现效果:

        用户选择地理区域看起来是这样的:

代码:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE>
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>信息发布</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	
	<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script>
	
	<script type="text/javascript" src="style/jquery-1.10.2.js"></script>

  </head>

<body>

<div style="width:100%;height:480px;border:1px solid gray" id="container"></div>
<p>
<input id="startBtn" type="button" onclick="startTool();" value="开始选取区域" />
<input type="button" onclick="map.clearOverlays();points=[];closeMark=0;document.getElementById('polygonArea').value='';" value="清除" />

<input type="hidden" id="polygonArea" value="" />
<hr>

	<table>
		<tr>
			<td>发布IDAAD信息:</td>
			<td><textarea name="message" id="message" clos="30" rows="7" style="height: 100%; width: 500px; 
				background-attachment: fixed; background-repeat: no-repeat; border-style: solid; 
				border-color: red";overflow-y:hidden;overflow-x:hidden;border:1;></textarea>
			</td>
		</tr>
		<tr>
			<td></td>
			<td>
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				<label><input name="mesType" type="radio" value="0" />推送信息</label> 
				<label><input name="mesType" type="radio" value="1" checked />广告信息</label> 
			</td>
		</tr>
		<tr>
			<td></td>
			<td>
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
				&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;
			<input type="button" value="&ensp;&ensp;&ensp;&ensp;发布信息&ensp;&ensp;&ensp;&ensp;" onclick="message()" />
			</td>
		</tr>
	</table>

<hr>

</body>  
</html>

<script type="text/javascript">
var map = new BMap.Map("container");
map.centerAndZoom("深圳", 12); 

map.enableScrollWheelZoom();

var key = 1; 
var newpoint;   
var points = [];   
var polyline = new BMap.Polyline(); 
var polygon;	
var closeMark = 0;
var dataPool = "";

function startTool(){

	if(key==1){
        document.getElementById("startBtn").style.background = "green";
        document.getElementById("startBtn").style.color = "white";
        document.getElementById("startBtn").value = "开启状态";
        key=0;
    } else{
        document.getElementById("startBtn").style.background = "red";
        document.getElementById("startBtn").value = "关闭状态";
        key=1;
    }
}
map.addEventListener("click",function(e){
	if(closeMark == 1){
		alert("已经闭合选择区域,请清除后重新选择!");
		return false;
	}

    newpoint = new BMap.Point(e.point.lng,e.point.lat);
    if(key==0){
	var markerhead = new BMap.Marker(newpoint);      
	map.addOverlay(markerhead);                   

        points.push(newpoint);  
        polyline.setPath(points); 
        map.addOverlay(polyline);  
	dataPool+=e.point.lng + "," + e.point.lat + "|";
    }
});

map.addEventListener("dblclick",function(e){
	if(key==0){
		closeMark = 1;
        map.disableDoubleClickZoom();
		polygon = new BMap.Polygon(points);
        map.addOverlay(polygon);
        
        var polygonArea=document.getElementById("polygonArea");
        polygonArea.value = dataPool;
    }
});

function submitFun(){
	if(key == 1){
		alert("您还没有选择区域!");
		return false;
	}
	if(closeMark == 0){
		alert("开始提交");
	}else{
		alert("您选择的区域没有闭合,请双击闭合!");
	}
}

function message(){
	var message=document.getElementById("message").value.trim();
	var mesTypes=document.getElementsByName("mesType");
	var polygonArea=document.getElementById("polygonArea").value.trim();
	var mesType="";
	
	if(key == 1){
		alert("您还没有选择区域!");
		return false;
	}
	
	if(closeMark == 0){
		alert("您选择的区域没有闭合,请双击闭合!");
		return false;
	}
	
	if ( polygonArea.length < 1 ) {
		alert("请选择区域");
		return false;
	};
	
	if ( message.length < 1 ) {
		alert("message不能为空");
		document.getElementById("message").focus();
		return false;
	};
	
    for(var i=0;i<mesTypes.length;i++){
        if(mesTypes[i].checked){ 
            //alert(mesTypes[i].value);
            mesType = mesTypes[i].value;
            break;
        }   
    }
    if ( mesType.length < 1 ) {
		alert("请选择消息类型!");
		return false;
	};
    
	$.ajax({
	  	url:'message',
		type:'GET',
		data:"UserLmessage="+message+"&mesType="+mesType+"&polygonArea="+polygonArea,
		success:function(data){
			if(data=="OK"){
				alert("发布成功!");
			}else{
				alert("发布失败!");
			}
		}
	});

}

</script>


        功能中的最难点,就是判断一个经纬度是否在广告投放的区域中。百度地图、高德地图只在javascriptAPI和AndroidSDK中提供了接口,所以如何判断成功了最大的难点,我想到的折中方法是在html页面中使用javascriptAPI中的接口进行判断,然后将判断结果回传到服务器中。

        javascriptAPI代码:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>行政区域工具</title>

<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>

String.prototype.getQueryString = function(name)
{
  var reg = new RegExp("(^|&|\\?)"+ name +"=([^&]*)(&|$)"), r;
  if (r=this.match(reg)) return unescape(r[2]); return null;
};
var polygonArea = location.search.getQueryString("polygonArea");
var carPoiont = location.search.getQueryString("carPoiont");

stringJudge(polygonArea,carPoiont);

function stringJudge(polygonArea,carPoiont){
	var points=[];
	var dps = polygonArea.split("|");
    for(var i=0;i<dps.length-1;i++){
		var dpArr = dps[i].split(",");
		var newpoint = new BMap.Point(dpArr[0],dpArr[1]);
		points.push(newpoint); 
    }

	var ply = new BMap.Polygon(points);

	var carPoionts = carPoiont.split(",");

    var pt =new BMap.Point(carPoionts[0],carPoionts[1]);
    
    var result = BMapLib.GeoUtils.isPointInPolygon(pt, ply);
    if(result == true){
	sentGeoResult(polygonArea,"YES");
    }else{
    
    }
}

function sentGeoResult(polygonArea,areaRangeMark){
	$.ajax({
        type: "GET",
        url: "GeoResult?date="+new Date().getTime(),  
        data: {areaRangeMark:areaRangeMark,polygonArea:polygonArea},
        success:function(data){
            
        }
 	});
}

</script>

</head>

</html>


        javascriptAPI很好的解决了这个难题,接下来如何在action中调用html页面,使之执行javascript代码并返回结果让我想了好久,使用了很多种方法还是无法重新调起执行,每一次都是将html页面获取过来,导致进度停滞了一天,今天终于让我找到了方法,嘿嘿~~~

        使用htmlunit完美的解决了这个问题,灵感来自于网络爬虫,htmlunit能够将网页读取出来,执行完网页的代码并返回结果。

        htmlunit代码:

public static void AreaJud(String url) throws Exception {
    final WebClient webClient = new WebClient();

    webClient.setAjaxController(new NicelyResynchronizingAjaxController());

    webClient.getPage(url);
}

        仅仅三行代码就解决了,当然htmlunit不止这点功能,使用htmlunit来做这个完全是大材小用,关于htmlunit的使用将在下一篇博客中介绍。

        

至此,推送广告功能就做完了,其实不止推送广告模块,在关于车辆防盗的电子围栏功能中也可以使用,估计还能做得更好。















© 著作权归作者所有

别寒
粉丝 30
博文 273
码字总数 155300
作品 0
永州
程序员
私信 提问
加载中

评论(4)

别寒
别寒 博主

引用来自“徐同乐”的评论

我准备在OpenWrt中把GFW加进去,黑名单就是这些推送广告的URL
我们推送广告是针对我们公司自己的设备的
别寒
别寒 博主

引用来自“大德易科”的评论

飘过
灵魂架构师
灵魂架构师
我准备在OpenWrt中把GFW加进去,黑名单就是这些推送广告的URL
懶蟲
懶蟲
飘过
OSChina 开源周刊 46 期,每周技术精粹

每周技术抢先看,总有你想要的! 开源资讯 2015 年 Android 碎片化情况让人吃惊 OpenSSL 将改用 Apache 2.0 许可协议 开源中国 Maven 镜像库重新上线,天翼云提供支持 Windows 开源 iOS 到 ...

OSC编辑部
2015/08/07
3.5K
4
极光品牌全面升级,三大产品体系震撼推出

6月,国内领先的一站式开发者服务平台极光推送发表公开声明,宣布品牌正式全面升级为大数据综合服务商“极光”,并隆重推出极光三大产品体系:极光开发者服务,极光广告服务与极光数据服务。...

Penny.
2016/06/13
2.3K
3
zengzhan/qqzeng-ip

qqzeng-ip 最新IP地址数据库-多语言解析以及导入数据库脚本 【全球旗舰版】【国内精华版】【国外拓展版】【CIDR掩码版】 dat格式(文件更小,查询更快,信息维度广,格式规范) txt格式(可以...

zengzhan
2018/08/21
0
0
如何解决区域内地图开发导航应用问题?

地图应用概述:随着地理信息的成熟化应用,地图出行已经必不可少。我们生活当中直接接触的大多都是基于网络平台的地图应用。所以对于web-GIS我们并不陌生,生活中我们或多或少都会接触到这类...

睡得
2015/05/28
769
2
个推荣获中国气象服务协会应急预警科技奖

10月19日, 由中国气象服务协会主办的“风云际会•中国气象服务协会2018年会”在南京信息工程大学圆满举办。本次年会主题为“智慧气象与产业发展”,来自中国气象局、部分省(区、市)气象局的...

个推君
2018/10/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
27分钟前
4
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
4
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
13
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
13
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部