web GIS地图打印
最近做了个小的功能,关于web GIS的地图打印功能,最终页就是将信息生成pdf。
整个流程如下:
1、在上侧的工具栏中添加一个打印按钮,如下图
2、单击打印按钮,弹出打印设置对话框,设置打印信息,标题,纸张大小,图标,
比例尺这一项没有用上,使用的是当前的地图比例尺,其中纸张大小,图标使用的是自定义标签从数据库中读取出来
3、点击OK按钮后打印对话框关闭,使用鼠标右键画框选定需要打印的区域。
4、换框完毕松开鼠标右键弹出pdf预览对话框。.
1、打印设置对话框就是open一个print.jsp
2、在关闭的时候调用父窗体对象中的方法,将所填信息传递给父窗体,这里的父窗体就是显示地图的jsp页面map.jsp.
使用var parentObj = window.dialogArguments;获得模式对话框的父窗体对象,
然后调用js方法
parentObj.selectPrintMap(title,scale,width,height,imgname);
title:地图标题 scale:比例尺
width:纸张宽度 height:纸张高度 imgname:图片名称
this.close();
3、画框选定地图调用了OpenLayers框架中的方法,OpenLayers原本只有拉框放大,拉框缩小地图,这里我小小的修改了一下OpenLayers.js中的代码
调用过程关键代码
.map.jsp:
function selectPrintMap(ptitle,scale,width,height,imgname){
g_mapPanel.toggleControl(“s_print”);
}
// g_mapPanel是在另一个js中的地图面板对象。
Core.js:
else if(Tools==“s_print”){
ZoomBoxPrint = new OpenLayers.Control.ZoomBox({out:“print”});
panelPrint = new OpenLayers.Control.Panel({defaultControl: ZoomBoxPrint});
panelPrint.addControls([ZoomBoxPrint]);
this.map.addControl(panelPrint);
panelPrint.destroy();
return ;
}
//这段代码是new一些拉框需要的控件
OpenLayers.js
OpenLayers.Control.ZoomBox=OpenLayers.Class(
OpenLayers.Control,
{
type:OpenLayers.Control.TYPE_TOOL,out:“zo”,
draw:function(){this.handler=new OpenLayers.Handler.Box(this,{done:this.zoomBox},{keyMask:this.keyMask});},
zoomBox:function(position){
if(position instanceof OpenLayers.Bounds){
if(this.out == “zo”){
var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));
var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));
var bounds=new OpenLayers.Bounds(minXY.lon,minXY.lat,maxXY.lon,maxXY.lat);
this.map.zoomToExtent(bounds);
}else if(this.out == “zi”){
var pixWidth=Math.abs(position.right-position.left);
var pixHeight=Math.abs(position.top-position.bottom);
var zoomFactor=Math.min((this.map.size.h/pixHeight),(this.map.size.w/pixWidth));
var extent=this.map.getExtent();
var center=this.map.getLonLatFromPixel(position.getCenterPixel());
var xmin=center.lon-(extent.getWidth()/2)*zoomFactor;
var xmax=center.lon+(extent.getWidth()/2)*zoomFactor;
var ymin=center.lat-(extent.getHeight()/2)*zoomFactor;
var ymax=center.lat+(extent.getHeight()/2)*zoomFactor;
var bounds=new OpenLayers.Bounds(xmin,ymin,xmax,ymax);
this.map.zoomToExtent(bounds);
}else{
var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));
var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));
printPreview(minXY,maxXY);
}
}else{
if(this.out == “zo”){
this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()+1);
}else if(this.out == “zi”){
this.map.setCenter(this.map.getLonLatFromPixel(position),this.map.getZoom()-1);
}
}
},
CLASS_NAME:“OpenLayers.Control.ZoomBox”
});
// out=“zo”,表示拉框放大,out=”zi”,表示拉框缩小,out=“print”就表示拉框选定要打印的地图区域,不对地图缩小或放大。OpenLayers源码中out为true或者false,我改动的也就是这个地方
当为拉框选区完毕松开鼠标右键时需要获取矩形框左下角最小点坐标对象 :minXY,右上角最大点坐标对象:maxXY,传递给map.jsp中的printPreview(minXY,maxXY)方法
else{
var minXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.left,position.bottom));
var maxXY=this.map.getLonLatFromPixel(new OpenLayers.Pixel(position.right,position.top));
printPreview(minXY,maxXY);
}
4、printPreview(minXY,maxXY)这个方法比较关键,来分析一下代码:
因为后台生成pdf的长宽大小单位为像素,打印跟像素也有一定关系,所以这里把一些数值转换成了像素长度。
function printPreview(minXY,maxXY){
var table_names = “${dataSet}_DATA.”+“${tableName}”.split(“:”)[1].split(“_”)[0]+“,”+m_inMapLayer;
var map_scale = g_mapPanel.map.getScale();//当前地图的比例尺
var p_layers = “”;//所有的图层
var screenPix = Math.round(window.screen.deviceXDPI / 2.54 * 10) / 10;//屏幕像素(像素/厘米)
if(layers_list == “”)
p_layers = “${tableName}”;
else p_layers = “${tableName},”+layers_list;
var map_width = maxXY.lon – minXY.lon;//选定区域的地图的实际宽
var map_height = maxXY.lat – minXY.lat; //选定区域的地图的实际高
var p_map_width = Math.round((1 / map_scale) * map_width * 1000);//根据比例尺得出图上宽度
var p_map_height = Math.round((1 / map_scale) * map_height * 1000);// 根据比例尺得出图上高度
var pix_map_width = Math.round(p_map_width / 10 * screenPix);// 将图上宽度转换为像素单位 var pix_map_height = Math.round(p_map_height / 10 * screenPix);// 将图上高度转换为像素单位
var pix_width = Math.round(p_width / 10 * screenPix);//纸张的像素宽 var pix_height = Math.round(p_height / 10 * screenPix);// 纸张的像素高
var url = g_geoserver+“/wms?bbox=”+minXY.lon+“,”+minXY.lat+“,”+maxXY.lon+“,”+maxXY.lat+“||styles=||Format=image/png||request=GetMap||version=1.1.1||layers=”+p_layers+“||width=”+pix_map_width+“||height=”+pix_map_height+“||srs=EPSG:${EPSG}”;//选定区域的地图图片路径,通过请求geoServer
var url2 = “${cpath}/webgis/WebGisAction.do?act=print&cpath=${urlPath}&title=”+p_title+“&scale=1 : “+p_scale+“&width=”+pix_width+“&height=”+pix_height+“&mapWidth=”+map_width+“&mapHeight=”+map_height+“&imgname=”+p_imgname+“&realPath=${realPath}&imgUrl=”+url;//将一系列参数传递至action,action转发至printPreview.jsp
var ar = new Array();
ar[0] = url2;
ar[1] = window;
showModalDialog(“${cpath}/common/popinput.htm”,ar,“resizable:yes;scroll:yes;dialogHeight:800px;dialogWidth:900px;center=yes”);
//打开对话框显示
转载自:https://blog.csdn.net/lansefeiyang122/article/details/83403489