webGIS實踐(geoserver+openlayer+django)4_3_python django配置靜態文件

一、配置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>操作方式 &nbsp;</label>
  <select id="interaction">
    <option value="search">查看</option>
    <option value="insert">增加</option>
    <option value="modify">修改</option>
    <option value="delete">刪除</option>
  </select>
  <label>先操作對象,再點擊 &nbsp;</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。因爲前端很難加密,所以有個後臺做跳轉,可以避免控制檯和數據庫被攻擊。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章