上图为最终效果,主要是实现以下几个功能
1地图上的坐标拖拽同时更新后台对应的经纬度。
2每个坐标的淡入弹出层支持对该坐标其它属性的修改。【手动修改校正】
3支持划线测距,将多个坐标之间的距离实时保存到后台。【系统自动校正】,坐标与坐标之间可以不为一条直线,最终保存的是一条直线或者多条直线的距离。
先需要引入openlayers2.13 和下面几个js文件
ol2.js
var SHADOW_Z_INDEX = 10;
var MARKER_Z_INDEX = 11;
var DIAMETER = 200;
var NUMBER_OF_FEATURES = 15;
var synFun = function(oX,oY,nX,nY){};
var updateDistanceFun = function(X,Y,distance){};
var timer = null;// 定时器函数,鼠标移入移出时使用
var _total_point = new Array();// 地图上显示的所有桩号
var _total_measure = 0.0;// 连线的总长度,单位(M),算上了起点桩号的距离,用于修改后面的桩号的里程
var _distance_measure = 0.0// 连线的总长度,单位(M), 未算上了起点桩号的距离,用于页面上显示点与点之间的距离
$dswork.map.v = {
map:null,
x:0,
y:0,
ll:null,
zoom:0,
minzoom:3,
maxzoom:17,
popups:[],
icon:null,
currntDrag:null,// 当前移动的Drag对象
currntDragX:0,// 当前移动的Drag对象的最初经度
currntDragY:0,// 当前移动的Drag对象的最初纬度
measureControls:null,
markers:null,//点
vector:null,
startSgin:null,//起点桩号
zoombox:null,
xy:new OpenLayers.Projection("EPSG:3857")
};
$dswork.map.controls = {
draws:null,//绘制点线面
measures:null,//量算点线面的距离或面积
selects:{select:null},
x:null,
use:function(v, o){
$dswork.map.clearControls();
try{var m = o[v];if(m){m.activate();$dswork.map.controls.x = m;}}catch(ex){}
},
draw: function(v){$dswork.map.controls.use(v, $dswork.map.controls.draws);},
measure:function(v){$dswork.map.controls.use(v, $dswork.map.controls.measures);},
select: function(v){$dswork.map.controls.use(v, $dswork.map.controls.selects);}
};
$dswork.map.events = {
featureselected:function(x){}
,featureunselected:function(x){}
};
$dswork.map.style = {
getStyle: function(){return {pointRadius:5,strokeColor:"#319730",strokeOpacity:1,strokeWidth:3,fillColor:"#acd5f6",fillOpacity:0.8,externalGraphic:getRootPath()+'/images/monitor_ico.png',graphicWidth:21,graphicHeight:25,graphicXOffset:-10,graphicYOffset:-25};}
,getSelect: function(){return {pointRadius:5,strokeColor:"#0000ff",strokeOpacity:1,strokeWidth:3,fillColor:"#948EF5",fillOpacity:0.8,externalGraphic:getRootPath()+'/images/marker-red.jpg',graphicWidth:21,graphicHeight:25,graphicXOffset:-10,graphicYOffset:-25,cursor:"pointer"};}
,getTemporary:function(){return {pointRadius:5,strokeColor:"#ff0000",strokeOpacity:1,strokeWidth:3,fillColor:"#948EF5",fillOpacity:0.8};}
,clear:function(o){o.externalGraphic=null;o.graphicWidth=null;o.graphicHeight=null;o.graphicXOffset=null;o.graphicYOffset=null;return o;}
};
$dswork.map.load = function(o){
var v = $dswork.map.v;
var styleMap;
v.x = o.x;
v.y = o.y;
v.zoom = o.zoom;
if(o.minzoom){
v.minzoom = o.minzoom;
}
if(o.maxzoom){
v.maxzoom = o.maxzoom;
}
var options = {
units:"m"
//,projection:new OpenLayers.Projection("EPSG:3857")//900913以米作为xy,4326以经纬度作为xy
,displayProjection:new OpenLayers.Projection("EPSG:3857")
,controls:[]
,minzoom:v.minzoom
,maxzoom:v.maxzoom
};
var deStyle = new OpenLayers.Style($dswork.map.style.getStyle());
deStyle.addRules(new OpenLayers.Rule({
symbolizer:{graphic:true,label:"${label}",labelSelect:true,externalGraphic:"./sdk/ol2/img/marker-gold.png"},
filter:new OpenLayers.Filter.Comparison({type:"==",property:"label",value:"p0"})
}));
styleMap = new OpenLayers.StyleMap({"default":deStyle,"select":$dswork.map.style.getSelect(),"temporary":$dswork.map.style.getTemporary()});
v.icon = new OpenLayers.Icon('./css/images/marker_sprite.png',new OpenLayers.Size(21,25),new OpenLayers.Pixel(-10, -25));//Pixel根据实际的图片作定位偏移,默认图片左上角
var bounds = new OpenLayers.Bounds(118.308865, 29.162737665, 120.87086111999999, 30.602299050000003); //设置地图边界
var map = v.map = new OpenLayers.Map("map", options);
var wms_layer = new OpenLayers.Layer.WMS("Base layer", "http://121.199.2.100:18080/geoserver/HzMap2015/wms",
{
layers: ["HzMap2015:HzMapGroups"], format: 'image/png' // 叠层
});
map.addLayers([ wms_layer ]);
map.zoomToExtent(bounds);
//重载地图方法,用于限制图层缩放级
map.isValidZoomLevel = function(zoomLevel) {
var valid = ( (zoomLevel != null) && (zoomLevel >= this.options.minzoom) && (zoomLevel <= this.options.maxzoom) );
return valid;
};
map.getNumZoomLevels = function(){return this.options.maxzoom+1;};
map.getMinZoom = function(){return this.options.minzoom;};
//添加wms图层
var markers = $dswork.map.v.markers = new OpenLayers.Layer.Markers("Markers", {styleMap:styleMap});//放置点图层
//map.addLayer(markers);
var vector = $dswork.map.v.vector = new OpenLayers.Layer.Vector('Vector', {styleMap:styleMap});//标注点线面图层
map.addLayer(vector);
$dswork.map.controls.selects.select = new OpenLayers.Control.SelectFeature(vector, {
clickout:true, toggle:false, multiple:false, hover:false, highlightOnly:false, box:false
,onSelect:function(evt){return $dswork.map.events.featureselected(evt);}
,onUnselect:function(evt){return $dswork.map.events.featureunselected(evt);}
});
$dswork.map.controls.selects.selectHover = new OpenLayers.Control.SelectFeature(vector, {
clickout:true, toggle:false, multiple:false, hover:true, highlightOnly:true, box:false
});
$dswork.map.v.map.addControl($dswork.map.controls.selects.select);
$dswork.map.v.map.addControl($dswork.map.controls.selects.selectHover);
$dswork.map.controls.selects.selectHover.activate();
//定义画点,线,面的对象.activate()激活绘画,.deactivate()禁用绘画
var c_draws = $dswork.map.controls.draws = {
point:new OpenLayers.Control.DrawFeature($dswork.map.v.vector, OpenLayers.Handler.Point)
,polyline:new OpenLayers.Control.DrawFeature($dswork.map.v.vector, OpenLayers.Handler.Path)
,polygon:new OpenLayers.Control.DrawFeature($dswork.map.v.vector, OpenLayers.Handler.Polygon)
,drag:new OpenLayers.Control.DragFeature($dswork.map.v.vector, {
autoActivate: true,
// 添加悬浮层,用于显示改桩号的信息
onEnter: function (feature) {
var enterPoint = $dswork.map.getPointByLonLat(feature.geometry.x, feature.geometry.y);
var p = $dswork.map.createPopup(null, new OpenLayers.LonLat(enterPoint.x, enterPoint.y), new OpenLayers.Size(0,20), "", false);
p.autoSize = true;
p.setContentHTML(
"" +
""+
"");
$dswork.map.v.map.addPopup(p);
$("#f_"+enterPoint.id).hover(function(){
clearTimeout(timer);
},function(){
timer = setTimeout(function(){$dswork.map.clearPopups();}, 500);
});
// 监听该点的表单提交事件
$("#f_"+enterPoint.id).form({
success:function(data){
data = eval('(' + data + ')');
$.messager.alert('提示', data.msg, 'info');
enterPoint.stakeNo = data.datas.stakeNo;
enterPoint.addKilometer = data.datas.addKilometer;
$dswork.map.updatePoint(enterPoint);
}
});
},
onLeave: function (feature) {
// 0.5秒关闭弹出桩号信息
timer = setTimeout(function(){$dswork.map.clearPopups();}, 500);
},
onStart: function (ft, pixel) {
currntDragX = ft.geometry.x;
currntDragY = ft.geometry.y;
},
// 当拖拽执行完毕,鼠标即将离开矢量要素时执行该函数。
onComplete: function (feature) {
var oX=currntDragX;
var oY=currntDragY;
var nX=feature.geometry.x;
var nY=feature.geometry.y;
synFun(oX,oY,nX,nY);// 钩子函数
}
})
};
map.addControl(c_draws.point);
map.addControl(c_draws.polyline);
map.addControl(c_draws.polygon);
map.addControl(c_draws.drag);
//map.addControl(new OpenLayers.Control.ModifyFeature($dswork.map.v.vector));
//定制拖动地图对象的操作类。激活可以拖动地图上的要素,到指定位置。
c_draws.drag.activate();
styleMap = new OpenLayers.StyleMap({"default":$dswork.map.style.clear($dswork.map.style.getStyle())});
//定义测量距离和面积的对象
var c_measures = $dswork.map.controls.measures = {
polyline:new OpenLayers.Control.Measure(OpenLayers.Handler.Path, {persist:true,handlerOptions:{layerOptions:{styleMap:styleMap}}})//layerOptions:{renderers:renderer}
,polygon:new OpenLayers.Control.Measure(OpenLayers.Handler.Polygon, {persist:true,handlerOptions:{layerOptions:{styleMap:styleMap}}})
};
c_measures.polyline.events.on({"measurepartial":function(f){
var arr = f.geometry.getVertices();
var c_x = arr[arr.length -2].x;
var c_y = arr[arr.length -2].y;
var m = arr[arr.length-1];
if(arr.length == 2){
$dswork.map.clearPopups();//第一次绘制,清空旧的
// 找到点击并且重合的桩号,获取桩号当前的桩号和桩号+,方面后面测距的时候做计算
startSgin = $dswork.map.checkPoint(c_y, c_x);
if(startSgin!=null){
var SginStart = $dswork.map.getPointByLonLat(startSgin.x, startSgin.y);
var km = parseInt(SginStart.stakeNo)*1000;// 千米
var m = parseInt(SginStart.addKilometer);// 米
_total_measure = km+m;
}else{
$.messager.alert('Info', "请准确选择一个起点桩号", 'info');
$dswork.map.measureLength();
}
}
if(arr.length > 2){
var s_x = arr[arr.length -3].x;// 用于算出最近两个点之间的距离
var s_y = arr[arr.length -3].y;// 用于算出最近两个点之间的距离
var fs = $dswork.map.v.vector.features;// 地图上标注的所有点
if(fs.length>2){
_total_measure += Math.round(getDistance(s_y, s_x, c_y, c_x));
_distance_measure += Math.round(getDistance(s_y, s_x, c_y, c_x));
var checkSign = $dswork.map.checkPoint(c_y, c_x);
if(checkSign!=null){
updateDistanceFun(checkSign.x, checkSign.y, Math.round(_total_measure));
}
}
}
var units = f.units;
var measure = f.measure; // 测量的距离
//var rs = units == "m" ? measure.toFixed(0) : measure.toFixed(1);
var rs = _distance_measure;
var p = $dswork.map.createPopup(null, new OpenLayers.LonLat(m.x, m.y), new OpenLayers.Size(0,20), "", false);
p.autoSize = true;
p.setContentHTML("" + (arr.length == 2 ? "起点" : (rs + " " + (units == "m" ? "米" : "公里"))) + "");
$dswork.map.v.map.addPopup(p);
},"measure":function(f){
var arr = f.geometry.getVertices();
var m = arr[arr.length-1];
var units = f.units;
var p = $dswork.map.createPopup(null, new OpenLayers.LonLat(m.x, m.y), new OpenLayers.Size(0,20), "", false)
p.autoSize = true;
p.setContentHTML("总长:" + _distance_measure + " " + (units == "m" ? "米" : "公里") + units + "");
$dswork.map.v.map.addPopup(p);
//console.log(arr);
}});
c_measures.polygon.events.on({"measurepartial":function(f){$dswork.map.clearPopups();}, "measure":function(f){
var arr = f.geometry.getVertices();
var m = arr[0];
//var order = f.order;if(order == 2){units = "平方" + units;}// 1距离,2面积
var p = $dswork.map.createPopup(null, new OpenLayers.LonLat(m.x, m.y), new OpenLayers.Size(0,20), "", false)
p.autoSize = true;
p.setContentHTML("" + f.measure.toFixed(2) + " 平方" + (f.units == "m" ? "米" : "公里") + "");
$dswork.map.v.map.addPopup(p);
}});
$dswork.map.v.label = OpenLayers.Util.createDiv("handleMeasurementsID", null, new OpenLayers.Size(0,25),null,"relative",null,null);
$dswork.map.v.map.viewPortDiv.appendChild($dswork.map.v.label);
map.addControl(c_measures.polyline);
map.addControl(c_measures.polygon);
map.addControl(new OpenLayers.Control.Navigation());//鼠标导航
map.addControl($dswork.map.v.zoombox = new OpenLayers.Control.ZoomBox());// 赋值并设置
map.addControl(new OpenLayers.Control.PanZoomBar({position:new OpenLayers.Pixel(2,6)}));//平移缩放工具条 左上
map.addControl(new OpenLayers.Control.MousePosition());//显示鼠标所在位置坐标 右下
map.addControl(new OpenLayers.Control.ScaleLine());//比例尺
map.addControl(new OpenLayers.Control.Permalink());//永久链接
map.addControl(new OpenLayers.Control.KeyboardDefaults());//键盘
$dswork.map.createPoint();
};
//清理
$dswork.map.clear = function(){
$dswork.map.clearControls();
$dswork.map.clearPopups();
$dswork.map.v.vector.removeAllFeatures();
$dswork.map.v.markers.clearMarkers();
};
$dswork.map.clearPopups = function(){
$dswork.map.clearLayerPopups();
$dswork.map.clearMapPopups();
};
$dswork.map.clearMapPopups = function(){
var v = $dswork.map.v;
for(var i = 0; i < v.popups.length; i++){
var p = v.popups[i];
try{v.map.removePopup(p);}catch(ex){}
}
v.popups.length = 0;
};
$dswork.map.clearLayerPopups = function(){
var r = $dswork.map.v.vector,f;
if(r.selectedFeatures != null) {
var n = 0;
while(r.selectedFeatures.length > n) {
f = r.selectedFeatures[n];
if(f.popup != null){
$dswork.map.v.map.removePopup(f.popup);
f.popup.destroy();//从要素中删除popup
f.popup = null;//设置为空
$dswork.map.controls.selects.select.unselect(f);
}
else{
++n;
}
}
}
};
$dswork.map.clearControls = function(){
if($dswork.map.controls.x != null){
$dswork.map.controls.x.deactivate();
$dswork.map.controls.x = null;
}
};
$dswork.map.createPopup = function(id, ll, size, html, switchClose){
var p = new OpenLayers.Popup(id, ll, size, html, switchClose);
$dswork.map.v.popups.push(p);
return p;
};
//点
$dswork.map.draw.point = function(p, o){
$dswork.map.controls.draws.point.events.remove("featureadded");
$dswork.map.controls.draw('point');
$dswork.map.controls.draws.point.events.on({"featureadded":function(evt){
var geometry=evt.feature.geometry.clone().transform($dswork.map.v.map.projection, $dswork.map.v.xy);
if(typeof o == "function"){
if(o('{"point":[' + geometry.x.toFixed(6) + ',' + geometry.y.toFixed(6) + ']}')){
//$dswork.map.draw.point(p, o);
}
else{
$dswork.map.controls.draws.point.deactivate();
}
}
else{
//$dswork.map.draw.point(p, o);
}
}});
};
//线
$dswork.map.draw.polyline = function(p, o){
$dswork.map.controls.draws.polyline.events.remove("featureadded");
$dswork.map.controls.draw('polyline');
$dswork.map.controls.draws.polyline.events.on({"featureadded":function(evt){
var geometry=evt.feature.geometry.clone().transform($dswork.map.v.map.projection, $dswork.map.v.xy);
var v = '{"polyline":[';
var arr = geometry.getVertices();
for(var i = 0; i < arr.length; i++){
v += '[' + arr[i].x.toFixed(6) + ',' + arr[i].y.toFixed(6) + '],';
}
v = v.slice(0, -1);
v += ']}';
if(typeof o == "function"){
if(o(v)){
//$dswork.map.draw.polyline(p, o);
}
else{
$dswork.map.controls.draws.polyline.deactivate();
}
}
else{
//$dswork.map.draw.polyline(p, o);
}
}});
};
//面
$dswork.map.draw.polygon = function(p, o){
$dswork.map.controls.draws.polygon.events.remove("featureadded");
$dswork.map.controls.draw('polygon');
$dswork.map.controls.draws.polygon.events.on({"featureadded":function(evt){
var geometry=evt.feature.geometry.clone().transform($dswork.map.v.map.projection, $dswork.map.v.xy);
var v = '{"polygon":[';
var arr = geometry.getVertices();
for(var i = 0; i < arr.length; i++){
v += '[' + arr[i].x.toFixed(6) + ',' + arr[i].y.toFixed(6) + '],';
//var xy = arr[i].transform($dswork.map.v.map.projection, $dswork.map.v.map.displayProjection);
}
v = v.slice(0, -1);
v += ']}';
if(typeof o == "function"){
if(o(v)){
//$dswork.map.draw.polygon(p, o);
}
else{
$dswork.map.controls.draws.polygon.deactivate();
}
}
else{
//$dswork.map.draw.polygon(p, o);
}
}});
};
//面积测量
$dswork.map.measureArea = function(){
$dswork.map.clearPopups();
$dswork.map.controls.measure('polygon');
};
//距离测量
$dswork.map.measureLength = function(){
$dswork.map.clearPopups();
$dswork.map.controls.measure('polyline');
};
//地图初始状态
$dswork.map.reset = function(){
$dswork.map.clear();
$dswork.map.resetZoomLevel();
};
$dswork.map.resetZoomLevel = function(){
var z = 0;
if(!$dswork.map.v.map.isValidZoomLevel($dswork.map.v.zoom)){
z = $dswork.map.v.map.options.minzoom;
}
else{
z = $dswork.map.v.zoom;
}
$dswork.map.v.map.setCenter(
$dswork.map.v.ll
,z
,true//是否触发 movestart/end事件
,true//是否触发zoomchange事件
);
//$dswork.map.v.map.zoomToMaxExtent();// 缩放到最大级别
$dswork.map.v.map.zoomTo(z);
};
//缩略图
$dswork.map.overview = function(){
$dswork.map.v.map.addControl(new OpenLayers.Control.OverviewMap());//鹰眼 右下
};
//右上角显示地图类型切换控件
$dswork.map.switcher = function(){
$dswork.map.v.map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false}));//图层切换 右上
};
//鼠标(null平移,true放大,false缩小)
$dswork.map.zoom = function(p){
$dswork.map.clearControls();
if(p == null){
}
else{
$dswork.map.controls.x = $dswork.map.v.zoombox;
if(p){
$dswork.map.v.zoombox.out = false;
}
else{
$dswork.map.v.zoombox.out = true;
}
$dswork.map.controls.x.activate();
}
};
//绘点
$dswork.map.createPoint = function(o, func){
if(o){
var layer = $dswork.map.v.vector;
var map =$dswork.map.v.map;
var center = map.getViewPortPxFromLonLat(map.getCenter());
var features = [];
features.push(
new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(o.x, o.y)
)
);
layer.addFeatures(features);
_total_point.push(o);
synFun = func;// 绑定钩子函数
}
};
//绘点
$dswork.map.caculateDistance = function(func){
updateDistanceFun = func;// 绑定钩子函数
};
// 找出测距的点是否与桩号有重合,如果重合,返回对应的桩号
$dswork.map.checkPoint = function(c_y, c_x ){
var fs = $dswork.map.v.vector.features;// 地图上标注的所有点
if(fs.length>2){
for(var i=0; i起点
dswork.map.js
if(typeof ($dswork) != "object"){$dswork = {};}
$dswork.map = {};
//json字符串转JSON对象
$dswork.map.toJSON = function (jsonstr){var o;eval("o = " + jsonstr);if(o){return o;}else{return {};}};
//加载地图(p{x, y, jb, poi}中心经度,中心纬度,缩放级别,默认地图POI是否可用) 并在左上角显示缩放控件、左下角显示比例尺
$dswork.map.load = function(p){};
//清理地图上绘制的所有图形
$dswork.map.clear = function(){};
//绘制点线面
$dswork.map.draw = {
point:function(p, fn){}//鼠标切换为绘制点工具 fn:callback(value) value={"point":[113.1,22.3]} callback返回true可画多个
,polyline:function(p, fn){}//鼠标切换为绘制线工具 fn:callback(value) value={"polyline":[113.1,22.3],[113.2,22.2],[112.3,22.2]} callback返回true可画多个
,polygon:function(p, fn){}//鼠标切换为绘制多边形工具 fn:callback(value) value={"polygon":[113.1,22.3],[113.2,22.2],[112.3,22.2]} callback返回true可画多个
};
//鼠标切换为面积测量工具<仅百度没有>
$dswork.map.measureArea = function(){};
//鼠标切换为距离测量工具
$dswork.map.measureLength = function(){};
//右下角显示缩略图(鹰眼)
$dswork.map.overview = function(){};
//右上角显示地图类型切换控件
$dswork.map.switcher = function(){};
//地图恢复初始状态
$dswork.map.reset = function(){};
//鼠标(null平移,true放大,false缩小)
$dswork.map.zoom = function(o){if(o==null){/*平移*/}else if(o){/*放大*/}else{/*缩小*/}};
//'{"point":[113.328488,23.240802]}';
//'{"polyline":[[113.287633,23.262567],[113.356297,23.262567],[113.396809,23.233862],[113.396466,23.213669]]}';
//'{"polygon":[[113.364880,23.198523],[113.348058,23.150233],[113.406766,23.147708],[113.431828,23.178957]]}';
//将json数组图形信息字符串显示在地图上
$dswork.map.show = function(jsonString){};
//加载地图并定位到用户城市<仅高德、百度> 并在左上角显示缩放控件、左下角显示比例尺
$dswork.map.loadmapGeo = function(){};
//定位用户<仅高德、百度>
$dswork.map.geolocal = function(fn){};
//坐标定位p{x,y}
$dswork.map.geoZB = function(p, fn){};
$dswork.map.creatgeometry = function(p, style, fn){};
//计算两点间距离(p{n1, e1, n2, e2}经度1、纬度1、经度2、纬度2)<百度、高德坐标单位为十进制度如:113.2333;arcgis坐标单位米> 返回值单位米
$dswork.map.distance = function(p){};
//显示信息窗体框<仅高德、百度> p{html,x,y,width}
$dswork.map.showInfo = function(p){};
//绑定事件(对象,事件名称,函数)
$dswork.map.bind = function(o, eventType, fn){};
//解绑事件
$dswork.map.unbind = function(eventType, o){};
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/common/global.jsp"%>
综合平台
<%@ include file="../../common/jsCss.jsp"%>
<%-- --%>
<%@ include file="../../common/header.jsp"%>
<%-- --%>
<%-- --%>
<%-- --%>
<%-- --%>
<%-- --%>
<%-- --%>
<%-- --%>
<%-- --%>