先看效果图:
openlayers案例+api:
https://openlayers.org/en/latest/examples/
https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html#removeLayer
ol3Echart参考网站:
https://sakitam-fdd.github.io/ol3Echarts/#/index
1.引入相关js+css文件,相关文件git地址:https://gitee.com/zhanglizeng/jarlist/tree/master/geoservice
<script th:src="@{/geoServiceNew/js/init/jquery-1.11.0.min.js}"></script>
<script th:src="@{/geoServiceNew/js/init/ol6.js}"></script>
<link rel="stylesheet" type="text/css" th:href="@{/geoServiceNew/css/init/ol6.css}"/>
<script th:src="@{/geoServiceNew/js/init/ol3Echarts.js}"></script>
2.页面定义div用户承接地图:
<div id="arcgisDiv" style="width:100%;height:100%;display:block;position: absolute;z-index: 2">
</div>
3.初始化图层和地图
//初始化图层
function initLayer(){
//背景图层
backgroundMapLayer = new ol.layer.Tile({
name: "背景",
zIndex: 0,
source: new ol.source.TileWMS({
url: geowebcacheUrl + '/geowebcache/service/wms',
params: {
'VERSION': '1.1.1',
'LAYERS': 'lwzx_bk',
'FORMAT': 'image/png',
'SRS': 'EPSG:3857'
},
tileGrid: new ol.tilegrid.TileGrid({
//resolution和conf.xml中保持一致
resolutions: [78271.517018034036, 39135.758509017018,
19567.879254508509, 9783.9394949623238,
4891.9698797730935, 2445.9849398865467,
1222.992337651342, 611.49616882567102,
305.74808441283551, 152.87417449834899,
76.436954957243259, 38.218609770552874,
19.109304885276437, 9.5546524426382184,
4.7773262213191092, 2.3886631106595546,
1.1943315553297773, 0.59716577766488865
],
tileSize: [256, 256],
origin: [-22041258.62706707, 33265069.154240012]
})
})
});
//政区名称图层
orgNameMapLayer = new ol.layer.Tile({
name: "标记",
zIndex: 2,
source: new ol.source.TileWMS({
url: geowebcacheUrl + '/geowebcache/service/wms',
params: {
'VERSION': '1.1.1',
'LAYERS': 'lwzx_zhuji',
'FORMAT': 'image/png',
'SRS': 'EPSG:3857'
},
tileGrid: new ol.tilegrid.TileGrid({
//resolution和conf.xml中保持一致
resolutions: [78271.517018034036, 39135.758509017018,
19567.879254508509, 9783.9394949623238,
4891.9698797730935, 2445.9849398865467,
1222.992337651342, 611.49616882567102,
305.74808441283551, 152.87417449834899,
76.436954957243259, 38.218609770552874,
19.109304885276437, 9.5546524426382184,
4.7773262213191092, 2.3886631106595546,
1.1943315553297773, 0.59716577766488865
],
tileSize: [256, 256],
origin: [-22041258.62706707, 33265069.154240012]
})
})
});
}
//初始化地图
function initMap(){
var projection = ol.proj.get('EPSG:3857'); //墨卡托投影空间参考坐标系
var view = new ol.View({
projection: projection, //坐标系如果不设置,默认为墨卡托
center: ol.proj.fromLonLat([104.408718, 39.922369]),
zoom: 4.5,
minZoom: 4,
maxZoom: 16
});
map = new ol.Map({
target: 'arcgisDiv',
layers: [backgroundMapLayer, orgNameMapLayer],
view: view,
controls: ol.control.defaults({ zoom: false })//加载比例尺控件overviewMapControl,
});
4.地图画点
var onePoint = new Array(); //第一个点的坐标
onePoint[0] = data.lon;
onePoint[1] = data.lat;
var popContent = "<ul style='padding-left:10px;padding-right:10px;font-size:14px;padding-bottom:10px;background-color:white'><li>桥梁编码:"+"t43t5ytrdghhttrh</li><li>桥梁名称:"+"</li><li>"+"所属省份:"+"</li><li>管养单位:"+"</li></ul>";
drawOnePoint(onePoint,"标题",popContent); //画一个点的方法--定义在geosevice.js中
//画一个点的方法,参数:经度、纬度
function drawOnePoint(onePoint,title,popContent){
var markListNew = [];
var rome = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat(onePoint)),
linkid: 'ceshilink',
popContent:popContent
});
rome.setStyle(new ol.style.Style({
image: new ol.style.Icon(({
src: "../geoService/image/mark_b.png"
})),
text: new ol.style.Text({
font: '15px Microsoft YaHei',
offsetY: -3,
text: title,
fill: new ol.style.Fill({
color: "#ffffFF"
})
}),
zIndex: 1
}));
markListNew.push(rome);
var vectorSource_point = new ol.source.Vector({
features: markListNew
});
var vectorLayer_point = new ol.layer.Vector({
name: "自定义打点图层",
source: vectorSource_point,
zIndex: 5
})
map.addLayer(vectorLayer_point);
}
5.点击地图时弹出提示框
(1)页面定义一个弹框div
<div id="popupWindow"> </div>
(2)自定义弹出框头部
var popTitle = "<ul><li><div style='width:100%;height:25px;background:#2C9EFF;color:white;font-size:16px;line-height:25px'><span style='padding-left:10px'>基本信息</span><span class='fa fa-close' style='float:left;color:#ffffff;font-size:16px;cursor:pointer;float:right;line-height:25px' onclick='hiddenPopWindow()' title='关闭'></span></div></li></ul>";
(3)初始化地图时添加点击监听
var container = document.getElementById("popupWindow");
windowOverlay = new ol.Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true
});
map.on('click',function(e){
//在点击时获取像素区域
var pixel = map.getEventPixel(e.originalEvent);
map.forEachFeatureAtPixel(pixel,function(feature){
//coodinate存放了点击时的坐标信息
var coodinate = e.coordinate;
//设置弹出框内容,可以HTML自定义
container.innerHTML = popTitle+feature.get("popContent");
//设置overlay的显示位置
windowOverlay.setPosition(coodinate);
//显示overlay
map.addOverlay(windowOverlay);
});
});
效果图
6.画线
var lineArr = new Array();
for(var i = 0;i < data.length;i++){
var onePoint = new Array(); //第一个点的坐标
onePoint[0] = data[i].lon;
onePoint[1] = data[i].lat;
lineArr.push(onePoint);
}
var popContent = "<ul style='padding-left:10px;padding-right:10px;font-size:14px;padding-bottom:10px;background-color:white'><li>路线名称:"+"t43t5ytrdghhttrh</li><li>桩号:"+"</li><li>"+"所属省份:"+"</li><li>管养单位:"+"</li></ul>";
drawOneLine(lineArr,"标题",popContent); //画一条线的方法--定义在geosevice.js中
//画一条线的方法--定义在geosevice.js中
function drawOneLine(lineArr,title,popContent){
var multiLineArr = [];
var line = [];
for (var i = 0; i < lineArr.length; i++) {
var coord = ol.proj.fromLonLat(lineArr[i])
line.push(coord)
}
multiLineArr.push(line);
var feature = new ol.Feature({
id: 'roadLines',
geometry: new ol.geom.MultiLineString(multiLineArr),
popContent:popContent
});
feature.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
width: 5,
color: 'green' //#1C86EE
}),
zIndex: 2
}));
var vectorSourceLine = new ol.source.Vector({
features: [feature]
});
var vectorLayerLine = new ol.layer.Vector({
name: "自定义画线图层",
source: vectorSourceLine,
zIndex: 1
});
map.addLayer(vectorLayerLine);
}
7.结合echart画饼图,需要给一个饼图的经纬度坐标值
//展示饼图表
function showPieCharts(){
pieEchartslayer = new ol3Echarts({
tooltip : {
trigger: 'item',
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
left: 'right',
show:false,
data: ['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
},
series: [
{
name: '访问来源',
type: 'pie',
radius : '30',
coordinates: [110.53450137499999, 33.44104525],
data: [
{value:335, name:'直接访问'},
{value:310, name:'邮件营销'},
{value:234, name:'联盟广告'},
{value:135, name:'视频广告'},
{value:1548, name:'搜索引擎'}
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
{
name: '访问来源',
type: 'pie',
radius : '30',
coordinates: [113.53450137499999, 34.44104525],
data: [
{value:335, name:'直接访问'},
{value:310, name:'邮件营销'},
{value:234, name:'联盟广告'},
{value:135, name:'视频广告'},
{value:1548, name:'搜索引擎'}
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
},
{
name: '访问来源',
type: 'pie',
radius : '30',
coordinates: [110.53450137499999, 38.44104525],
data: [
{value:335, name:'直接访问'},
{value:310, name:'邮件营销'},
{value:234, name:'联盟广告'},
{value:135, name:'视频广告'},
{value:1548, name:'搜索引擎'}
],
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
});
pieEchartslayer.appendTo(map);
}
多个饼图时需要一次性组织好数据,否则有层级问题,只有最后一个饼图鼠标放上去出提示信息,组织数据形式:
function loadRoadPieForJsdj(aprotxt){
var legendData = ['高速', '一级', '二级', '三级', '四级', '等外'];
var unit = "公里";
var seriesList = [];
var itemStyle = getPieItemStyle(); //得到饼图样式的方法
for (var j = 0; j < aprotxt.length; j++){ //遍历结果集放到数组中
if("66" != aprotxt[j].id){
var seriesData = [];
var object0 = new Object();
object0.value = aprotxt[j].length10;
object0.name = legendData[0];
seriesData.push(object0);
var object1 = new Object();
object1.value = aprotxt[j].length11;
object1.name = legendData[1];
seriesData.push(object1);
var object2 = new Object();
object2.value = aprotxt[j].length12;
object2.name = legendData[2];
seriesData.push(object2);
var object3 = new Object();
object3.value = aprotxt[j].length13;
object3.name = legendData[3];
seriesData.push(object3);
var object4 = new Object();
object4.value = aprotxt[j].length14;
object4.name = legendData[4];
seriesData.push(object4);
var object5 = new Object();
object5.value = aprotxt[j].length15;
object5.name = legendData[5];
seriesData.push(object5);
var coordinates= GetProvPoint(aprotxt[j].id); //通过省份编码得到图表显示的经纬度位置(定位在map_doc.js文件中)
var seriesOne = new Object();
seriesOne.name = aprotxt[j].name;
seriesOne.type = 'pie';
seriesOne.radius = '30';
seriesOne.coordinates = coordinates;
seriesOne.data = seriesData;
seriesOne.itemStyle = itemStyle;
seriesList.push(seriesOne);
}
}
if(null != seriesList && seriesList.length > 0){
pieEchartslayer = new ol3Echarts({
tooltip : {
trigger: 'item',
formatter: "{a} {b} : {c} ({d}%)"+unit
},
legend: {
orient: 'vertical',
left: 'right',
show:false,
data: legendData
},
color : eColor,
series:seriesList
});
pieEchartslayer.appendTo(map);
}
}
//得到饼图样式的方法
function getPieItemStyle(){
var emphasis = new Object();
emphasis.shadowBlur = '10';
emphasis.shadowOffsetX = '0';
emphasis.shadowColor = 'rgba(0, 0, 0, 0.5)';
var label = new Object();
label.show = false;
var labelLine = new Object();
labelLine.show = false;
var normal = new Object();
normal.label = label;
normal.labelLine = labelLine;
var itemStyle = new Object();
itemStyle.emphasis = emphasis;
itemStyle.normal = normal;
return itemStyle;
}
//通过省份编码得到图表显示的经纬度位置
function GetProvPoint(aCode){
switch(parseInt(aCode))
{
case 11:
return([116.390305,39.913533]);
break;
case 12:
return([117.181559, 39.140267]);
break;
case 13:
return([114.491961, 38.047298]);
break;
case 14:
return([112.555008, 37.870592]);
break;
case 15:
return([111.64708, 40.812369]);
break;
case 21:
return([123.38481, 41.795712]);
break;
case 22:
return([125.31284, 43.883023]);
break;
case 23:
return([126.681423, 45.728073]);
break;
case 31:
return([121.477575, 31.222797]);
break;
case 32:
return([118.782832, 32.048415]);
break;
case 33:
return([120.167095, 30.250499]);
break;
case 34:
return([117.267471, 31.795161]);
break;
case 35:
return([119.306406, 26.076106]);
break;
case 36:
return([115.828639, 28.657307]);
break;
case 37:
return([117.014735, 36.669959]);
break;
case 41:
return([113.663619, 34.76298]);
break;
case 42:
return([114.325985, 30.553486]);
break;
case 43:
return([112.995762, 28.19804]);
break;
case 44:
return([113.31292, 23.119668]);
break;
case 45:
return([108.32314, 22.829835]);
break;
case 46:
return([110.331133, 20.015867]);
break;
case 50:
return([106.532207, 29.536664]);
break;
case 51:
return([104.073939, 30.659293]);
break;
case 52:
return([106.708467, 26.58234]);
break;
case 53:
return([102.703007, 25.044456]);
break;
case 54:
return([91.12466, 29.656367]);
break;
case 61:
return([108.944245, 34.264881]);
break;
case 62:
return([103.750794, 36.069861]);
break;
case 63:
return([101.771469, 36.623047]);
break;
case 64:
return([106.266638, 38.47107]);
break;
case 65:
return([87.605163, 43.810314]);
break;
case 1:
return([121.477575, 31.222797]);
break;
case 2:
return([114.325985, 30.553486]);
break;
case 3:
return([101.771469, 36.623047]);
break;
}
switch(aCode){
case "XN":
return([104.073939, 30.659293]);
break;
case "XB":
return([101.771469, 36.623047]);
break;
case "HZ":
return([112.995762, 28.19804]);
break;
case "HN":
return([113.31292, 23.119668]);
break;
case "HD":
return([121.477575, 31.222797]);;
break;
case "HB":
return([116.390305,39.913533]);
break;
case "DB":
return([125.31284, 43.883023]);
break;
default:
return([116.390305,39.913533]);
}
}
8.画柱状图
//展示柱图表
function showBarCharts(){
var options = {
color: ['#3398DB'],
tooltip : {
trigger: 'axis',
axisPointer : { // 坐标轴指示器,坐标轴触发有效
type : 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
x: "left",
show: false,
data: ['包租费', '物业费', '水电', '网络', '燃气'],
selectedMode: 'multiple'
},
grid: [],
xAxis : [],
yAxis : [],
series: []
}
var series = [
{
name: '包租费',
type: 'bar',
barWidth: '15',
coordinates: [87.1435546875, 43.79150390625],
data: [20, 12, 31, 34, 31],
xAxisIndex: 0,
yAxisIndex: 0
},
{
name:'物业费',
type:'bar',
barWidth: '15',
coordinates: [86.5283203125, 32.40966796875],
data: [1, 1, 2, 3, 1],
xAxisIndex: 1,
yAxisIndex: 1
},
{
name:'水电',
type:'bar',
barWidth: '15',
coordinates: [98.876953125, 35.74951171875],
data: [1, 1, 2, 3, 1],
xAxisIndex: 2,
yAxisIndex: 2
},
{
name:'网络',
type:'bar',
barWidth: '15',
coordinates: [108.80859375, 23.44482421875],
data: [1, 1, 2, 3, 1],
xAxisIndex: 3,
yAxisIndex: 3
},
{
name:'燃气',
type:'bar',
barWidth: '15',
coordinates: [120.53450137499999, 44.44104525],
data: [1, 1, 2, 3, 1],
xAxisIndex: 4,
yAxisIndex: 4
}
];
series.forEach(function (item, index) {
options.grid.push({
show: true,
containLabel: false,
borderWidth: 0,
borderColor: '#fff',
width: 150,
height: 80
});
options.xAxis.push({
type : 'category',
show: true,
gridIndex: index,
nameTextStyle: {
color: '#3c3c3c'
},
axisLine: {
show: false,
onZero: false
},
axisLabel: {
show: false,
interval: 0,
rotate: -45,
textStyle: {
color: '#3c3c3c',
fontSize: 10
}
},
axisTick: {
show: false
},
data : ['新虹桥', '中山公园', '虹桥', '镇宁路', '天山古北']
});
options.yAxis.push({
type: 'value',
show: true,
min: 0.001,
splitLine: {show: false},
axisLabel: {
show: false
},
axisLine: {
show: false,
onZero: false
},
nameGap: '1',
axisTick: {
show: false
},
nameTextStyle: {
color: '#3c3c3c',
fontSize: 14
},
gridIndex: index
});
options.series.push(item)
})
barEchartslayer = new ol3Echarts(options);
barEchartslayer.appendTo(map);
}
9.清除地图加载的echart图,layer
//清除所有的图层
function Draw_clear(){
if(null != pieEchartslayer){
pieEchartslayer.remove(); //移出,避免重复添加.
}
if(null != barEchartslayer){
barEchartslayer.remove(); //移出,避免重复添加.
}
if(null != orgLayerArr && orgLayerArr.length > 0){
for(var i = 0;i < orgLayerArr.length;i++){
map.removeLayer(orgLayerArr[i]);
}
orgLayerArr = [];
}
}
10.给地图每个政区按图例的颜色上色,上色由各个政区的结果值匹配
//初始化政区图像坐标
function initOrgPolygon(){
$.ajax({
type:'get',
url: geowebcacheUrl+'/geoserver/sf/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=sf%3Aprovince_borderline&maxFeatures=50&outputFormat=application%2Fjson',
dataType:'json',
data:null,
success:function(data){
orgPolygonArr = data;
},
error:function(){
orgPolygonArr = null;
showMsg("查询数据错误,请稍后重试","danger",1200,"center","center");
}
});
}
var vclr33 = 0.8; //颜色透明度
//公路里程颜色
var roadColor1=[189,219,239, vclr33];
var roadColor2=[135,192,232, vclr33];
var roadColor3=[50,139,203, vclr33];
for (var i = 0; i < orgPolygonArr.features.length; i++) { //查询地图服务得到结果集合,遍历结果集合
var Polygons = orgPolygonArr.features[i]; //Polygons定义在map_.js文件中,用于临时记录地图服务结果单个值
for(var j = 0;j < dataArr.length;j++){
if(dataArr[j].id == Polygons.properties.adminsheng){//省份编码一致
var color = roadColor1;
switch(parseInt(dataArr[j].alevel)) { //根据颜色等级设置颜色参数
case 1:color = roadColor1;break; //颜色值设置在map_.js文件中,需要改动颜色则直接去总此文件中设置
case 2:color = roadColor2;break; //vcolor33定义在map_.js中,具备初始默认颜色
case 3:color = roadColor3;break;
}
drawOneOrgLayer(color,Polygons); //在layer17上传递结果值,颜色等级,鼠标放上去的提示信息(定义在map_doc.js文件中)
}
}
}
//在图层上传递结果值,颜色等级,鼠标放上去的提示信息
function drawOneOrgLayer(color,Polygon){
//创建一个多变形
var Polygon = new ol.Feature({
geometry: new ol.geom.Polygon(Polygon.geometry.coordinates)
});
//设置区样式信息
Polygon.setStyle(new ol.style.Style({
//填充色
fill: new ol.style.Fill({
color: color
}),
//边线颜色
stroke: new ol.style.Stroke({
color: '#F0F0F0',
width: 2
}),
//形状
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: color
})
})
}));
var vectorSource_area = new ol.source.Vector({
features: [Polygon]
})
var vectorLayer_area = new ol.layer.Vector({
name: "自定义画面图层",
source: vectorSource_area,
zIndex: 1
})
orgLayerArr.push(vectorLayer_area); //添加到数组中,用于清除图层时使用
map.addLayer(vectorLayer_area);
}
11.鼠标移动简体:当底图及echarts都需要有提示信息时,设置底图的提示信息在图表之下,这样才能显示echart的提示信息,设置弹出框的stopEvent: false
var container = document.getElementById("popupWindow");
windowOverlay = new ol.Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true,
// 如果设置为ture,那么叠置层被放在装载控件的那个div容器中(该div容器css类名为ol-overlaycontainer-stopevent)
// 如果设置为false,那么叠置层被放在css类名为ol-overlaycontainer的div容器下,由className属性(默认为'ol-overlay-container ol-selectable')指定类名的div容器中
stopEvent: false
});
map.addOverlay(windowOverlay);