一、配置js和css
網頁訪問需要配置的圖片、js、css都是靜態文件。配置靜態文件的目的是,當程序啓動的時候,可以通過url來獲取這些內容。
settings.py中添加:
STATIC_URL = '/static/'
STATICFILES_DIRS=[
os.path.join(BASE_DIR, "static_files"),
]
新建一個static_files文件夾,靜態文件都放在這裏面。
將ol.js和ol.css複製到static_files中。
運行:python manage.py runserver 0.0.0.0:5000
訪問:127.0.0.1:5000/static/ol/ol.js
效果:
二、配置html
在geoserver.py中添加方法:
# 渲染geoserver頁面
def geoserverget(request):
return render(request, 'GeoserverOL.HTML')
在urls.py中添加鏈接:
url(r'^geoserver$', geoserver.geoserverget),
在templates中添加GeoserverOL.HTML。
GeoserverOL.HTML代碼如下,主要是{% load static %}加載靜態文件,{% static 'ol/ol.css'%}配置靜態文件。
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>openlayer與geoserver交互</title>
<link rel="stylesheet" href="{% static 'ol/ol.css'%}">
<script src="{% static 'ol/ol.js'%}"></script>
<script src="{% static 'jquery-1.7.2.js'%}"></script>
<style type="text/css">
#map,
html,
body {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<form class="form-inline">
<label>操作方式 </label>
<select id="interaction">
<option value="search">查看</option>
<option value="insert">增加</option>
<option value="modify">修改</option>
<option value="delete">刪除</option>
</select>
<label>先操作對象,再點擊 </label>
<input type="button" id="creategml" name="name" value="提交" />
</form>
<div id="map"></div>
<div id="attributetable">
<table>
<thead>
<tr>
<th>fid</th>
<th>name_py</th>
<th>name_ch</th>
</tr>
</thead>
<tbody id="attributetbody">
</tbody>
</table>
</div>
</body>
<script type="text/javascript">
//線上線下訪問url不同,可變配置提出
var baseurl ='http://localhost:8080/';
// 獲取座標系
var proj4326=ol.proj.get('EPSG:4326');
// 打印座標系的軸方向,默認的軸方向爲neu,生成GML文件,經緯度會是反的
console.log(proj4326.getAxisOrientation());
// 新建座標系,修改軸方向爲enu,經度、緯度、高程
var proj = new ol.proj.Projection({ code: 'EPSG:4326',
axisOrientation: 'enu',
units:proj4326.getUnits(),
canWrapX:true,
extent:proj4326.getExtent(),
global:true,
worldExtent:proj4326.getWorldExtent(),
});
// 覆蓋原來的4326座標系,目的是爲了保證生成GML文件中經緯度不反
ol.proj.addProjection(proj);
var proj4326new=ol.proj.get('EPSG:4326');
console.log(proj4326new);
//視窗,openlayer默認座標系是平面墨卡託,設定爲WGS84
var view = new ol.View({
center: [116.400146,40.250184],
zoom: 9,
projection: 'EPSG:4326',
});
//圖層,加載騰訊底圖和geoserver發佈的wmts
var layers = [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: "http://rt{0-3}.map.gtimg.com/realtimerender?z={z}&x={x}&y={-y}&type=vector&style=0"
})
}),
new ol.layer.Image({
source: new ol.source.ImageWMS({
ratio: 1,
url: 'http://localhost:8080/geoserver/wms?',//這個可以打開geoserver的preview,看openlayer頁面截取url
// 請求參數
params: {
'SERVICE': 'WMS',
'VERSION': '1.1.0',
'REQUEST': 'GetMap',
'FORMAT': 'image/png',
'TRANSPARENT': true,
'tiled': true,
'LAYERS': 'gismap:v6_time_pref_pgn_utf_wgs84_geoserver',//圖層,前面是工作空間,後面是圖層名,
'exceptions': 'application/vnd.ogc.se_inimage',
'singleTile': true//單瓦片,渲染成一張圖片
}
}),
}),
];
//地圖
var map = new ol.Map({
target: 'map',
layers: layers,
view: view
});
// 添加工具圖層,新增、修改、刪除選擇都在這個圖層上進行
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
source: source,
style: polygonStyleFunction
});
map.addLayer(vector);
// 僅以繪製面舉例
var draw = new ol.interaction.Draw({
source: source,
type: "Polygon"
});
// 定義選擇控件與修改控件
var select = new ol.interaction.Select({
wrapX: false
});
var modify = new ol.interaction.Modify({
features: select.getFeatures()
});
// 變化時觸發
var typeInteraction = document.getElementById('interaction');
typeInteraction.onchange = function() {
map.removeInteraction(select);
map.removeInteraction(modify);
map.removeInteraction(draw);
if (typeInteraction.value=='insert'){
map.addInteraction(draw);
}
if (typeInteraction.value=='modify'){
map.addInteraction(select);
map.addInteraction(modify);
}
};
// 完成繪製(drawend)時激活
draw.once("drawend",function (e) {
// draw工具不可用
draw.setActive(false);
// 屬性框
var tabletxt='<tr><td>'
+'<input type="text" id="fid" value="fid" />'+'</td><td>'
+'<input type="text" id="name_py" value="name_py" />'+'</td><td>'
+'<input type="text" id="name_ch" value="name_ch" />'+'</td></tr>';
$("#attributetbody").append(tabletxt);
});
// 點擊按鈕向geoserver提交數據
$("#creategml").click(function() {
if (typeInteraction.value=='search'){
alert('支持insert update delete');
}
// 獲取feature列表
var features=source.getFeatures();
// 獲取一個feature
var feature=features[0];
var fid=$("#fid").val();
var name_py=$("#name_py").val();
var name_ch=$("#name_ch").val();
// update和delete的時候需要fid
feature.setId(fid);
feature.set('name_py',name_py);
feature.set('name_ch',name_ch);
// 創建WFS解析器
var WFSTSerializer = new ol.format.WFS();
var insertFeatures=[];
var updateFeatures=[];
var deleteFeatures=[];
if (typeInteraction.value=='insert'){
insertFeatures.push(feature);
}
if (typeInteraction.value=='modify'){
var updatefeature=select.getFeatures().getArray()[0];
updatefeature.setId(fid);
updatefeature.set('name_py',name_py);
updatefeature.set('name_ch',name_ch);
updateFeatures.push(updatefeature);
}
if (typeInteraction.value=='delete'){
deleteFeatures.push(feature);
}
// 格式:writeTransaction(inserts, updates, deletes, options)
// updates和deletes都需要要素有唯一ID,進行索引
// insert因爲是新增,所以不需要
var featObject = WFSTSerializer.writeTransaction(insertFeatures,
updateFeatures, deleteFeatures, {
featureNS: 'http://geoserver/mapgis',//工作區URI
featurePrefix: 'gismap',//工作區名稱
featureType: 'gismap:v6_time_pref_pgn_utf_wgs84_geoserver',//圖層名稱
srsName: 'EPSG:4326',//座標系
});
var serializer = new XMLSerializer();
var featString = serializer.serializeToString(featObject);
// 打印到控制檯看看效果,openlayer默認生成的GML中幾何字段名爲geometry
console.log(featString);
// 清空屬性表
$("#attributetable").html('<table><thead><tr><th>fid</th><th>name_py</th><th>name_ch</th></tr></thead><tbody id="attributetbody"></tbody></table>');
// 上傳到geoserver
$.ajax({
type: 'POST',
url: baseurl+'geoserver/wfs',
contentType:'text/xml',
data: featString,
dataType: 'json',
success: function(data){
source.removeFeature(feature);
console.log(data);
},
error:function(data){
source.removeFeature(feature);
console.log(data);
}
});
})
//地圖點擊事件
$("#map").click(function (e) {
if (typeInteraction.value=='insert'){
return;
};
if (typeInteraction.value=='modify'){
return;
};
if (typeInteraction.value=='delete'){
return;
};
//獲取地圖上點擊的地理座標,WGS84座標系
var t4326=map.getEventCoordinate(e);
//構造請求url
var url4326=baseurl+'geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image%2Fpng&TRANSPARENT=true&QUERY_LAYERS=gismap%3Av6_time_pref_pgn_utf_wgs84_geoserver&LAYERS=gismap%3Av6_time_pref_pgn_utf_wgs84_geoserver&exceptions=application%2Fvnd.ogc.se_inimage&INFO_FORMAT=application/json&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG%3A4326&STYLES=&WIDTH=101&HEIGHT=101&BBOX='+(t4326[0]-0.0001).toString()+'%2C'+(t4326[1]-0.0001).toString()+'%2C'+(t4326[0]+0.0001).toString()+'%2C'+(t4326[1]+0.0001).toString();
$.ajax(
{
url:url4326,
type:'GET',
dataType:'json',
headers:{'Content-Type':'application/json;charset=utf8'},
success:function(data){
//這個方法直接把geojson轉爲feature數組
features=(new ol.format.GeoJSON()).readFeatures(data);
// 將feature數組中第一個feature放到source中
source.addFeature(features[0]);
//更新屬性表
var fid=data['features'][0]['id'];
var properties=data['features'][0]['properties'];
var name_py=properties['name_py'];
var name_ch=properties['name_ch'];
var tabletxt='<tr><td>'
+'<input type="text" id="fid" value="'+fid+'" />'+'</td><td>'
+'<input type="text" id="name_py" value="'+name_py+'" />'+'</td><td>'
+'<input type="text" id="name_ch" value="'+name_ch+'" />'+'</td></tr>';
$("#attributetbody").append(tabletxt);
},
error:function(data){
console.log('faile');
console.log(data);
}
}
);
});
//製圖風格,標註內容要從要素中獲取,每個要素的name_ch屬性不同,所以製圖風格是方法,而不是靜態的
function polygonStyleFunction(feature) {
return new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'rgba(192, 0, 0, 1)',
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(192, 192, 192, 0.5)'
}),
text: createTextStyle(feature)
});
};
//創建註記
function createTextStyle(feature) {
return new ol.style.Text({
font: '20px Microsoft YaHei',
text: getText(feature),
fill: new ol.style.Fill({
color: 'rgba(192, 0, 0, 1)'
}),
stroke: new ol.style.Stroke({color: 'rgba(255, 255, 255, 1)', width: 1}),
})
};
//獲取要素屬性內容
function getText(feature) {
if (feature.get('name_ch')){
return feature.get('name_ch').toString();
} else{
return 'tool';
}
};
</script>
<style type="text/css">
#map {
width: 100%;
height: 100%;
}
#attributetable {
width: 100%;
height: 5%;
margin: 10px;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
}
th,td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
th {
background-color: #C00000;
font: bold 16px "微軟雅黑";
color: #fff;
}
td {
font: 14px "微軟雅黑";
}
tbody tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
</style>
</html>
三、效果
啓動geoserver。
訪問:http://127.0.0.1:5000/geoserver
頁面已經能訪問和操作了。
我們還需要看通過django訪問WMS服務,而不是直接訪問geoserver。因爲前端很難加密,所以有個後臺做跳轉,可以避免控制檯和數據庫被攻擊。