iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 2
4
Modern Web

30天打造我的WebGIS系列 第 2

[Day 2] WebGIS初步

  • 分享至 

  • xImage
  •  

WebGIS:從Client端及Server端談起

Clinet端:

跟一般網頁應用程式一樣,webgis需要前端程式與使用者互動,要開發一個webgis,開發者可以使用各種前端框架。
然而,要炒一盤webgis的菜,就必須要有專屬於gis/地圖的前端框架
這些框架主要功能包含提供地圖,圖層渲染,基本地圖互動、介接資料等功能,Javascript常見的webgis框架包含:

  • (1)leaflet
  • (2)openlayers
  • (3)google maps api
  • (4)esri javascript api

一個地圖框架提供我們基本地圖操作,把地圖元素(含空間坐標物件)轉換成前端可操作的元件(DOM等),而為使地圖互動更生動活潑,其它前端工具當然也是可以整合進來的,包含Jquery, Vue, React, Angularjs...甚至D3.js, C3.js等可能都需要整合在webGIS中。

Server端:Web service及資料庫

在webGIS應用程式中,可以透過Web service來進行資料操作,這之中最常使用到的是網路圖磚服務(WMTS),例如我們透過 Google maps api 在網頁之中建立一個地圖,這時可以看到Google maps的底圖,這個底圖服務就是透過類似WMTS的概念來實作的。

另一個面向是資料庫,具有空間資料的資料庫稱作「空間資料庫」,空間資料庫能夠執行各種空間查詢,目前包含MSSQL(SQL Spatial)Postgressql(PostGIS)Oracle(Oracel Spatial)MySQLMongoDB等各大資料庫系統都有支援空間資料庫的格式及模組。

先直接來個範例

上面長篇大論講了一堆,本次鐵人賽的目標是把能說清楚這些事情,並加強資料特性的探討,議題逐一擊破。

以下先快速開始一個範例,看一下一個webGIS大致組成:
我們使用leaflet.js new一個地圖並以線上WMTS作為底圖,並把一些資料放上圖台,
這樣其實就是最簡單的一個WebGIS。

引入必要元件

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>

初始化一個地圖並設定中心經緯度為[25.0375928,121.5529563], 比例尺為10的視角

<div id='map_div' style="height:100%"></div>
var map = L.map('map_div').setView([25.0375928,121.5529563], 10);

一個地圖應用都需要底圖,這邊我們使用官方維護的內政部國土測繪中心wmts

var basemap = L.tileLayer('https://wmts.nlsc.gov.tw/wmts/EMAP/default/GoogleMapsCompatible/{z}/{y}/{x}', {
        attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);

接下來,webGIS都會有自己的資料,可能是靜態的,也可以是需要資料庫IO的
可能需要從Server side 寫一個api接口取資料
c#:(示意)

//取資料接口..
[Route("api/Poi")]
[httpget] 
public JsonResult Poi()
{    
   //Bson collection example [{"name":"市府店","geo":[25.0375,121.5529]},{"name":"西門店","geo":[25.0401,121.509]}....]
   List<PoiDataModel> pois =  List<PoiDataModel>();
   //取資料...
   略..
   return Json(...)
}

client side:
接上面的api,把資料放在地圖上

$.ajax({
    url: "/api/Poi",
    contentType: 'application/json',
    type: 'GET',
    contentType: 'application/json; charset=utf-8',
    success: function(data) {
         $.each(data.pois, function(k, v) {
            L.marker([v[0], v[1]]).addTo(map)
            .bindPopup(v.name)
            .openPopup();
         });
    }
});

另外,可能需要介接其它api資料,我們的範例資料是一個展店的計畫,
在此,我們有需求是看看周圍的商家資料。
這邊我們介接經濟部開放資料
說明: A-3 鄰近商家查詢:透過坐標參數,查詢所在位置鄰近商家清冊資料。

接到的資料是geojson,把它們放到地圖上
並以不同符號表示

$.ajax({
   url: "https://egis.moea.gov.tw/MoeaEGFxData_WebAPI_Inside/InnoServe/BusinessBUSM?resptype=GeoJson&x=121.509&y=25.0401&buffer=1000",
   type: 'GET',
   success: function (data) {
       var symbol = {
            radius: 3,
            fillColor: "#ff7800",
            color: "#000",
            weight: 1,
            opacity: 1,
            fillOpacity: 0.8
       };
       L.geoJSON(data, {
            pointToLayer: function (feature, latlng) {
                return L.circleMarker(latlng, symbol);
                }
        }).addTo(map);
    }
});

完整程式碼

client side(map.html):

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>


<div id='map_div' style="height:100%"></div>
<script>
//利用leaflet初始化地圖
var map = L.map('map_div').setView([25.0375928,121.5529563], 10);

//加入內政部國土測繪中心wmts
var basemap=L.tileLayer('https://wmts.nlsc.gov.tw/wmts/EMAP/default/GoogleMapsCompatible/{z}/{y}/{x}', {
        attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

//從Server端API接口把POI展在地圖上,並binding一個popup
$.ajax({
    url: "/api/Poi",
    contentType: 'application/json',
    type: 'GET',
    contentType: 'application/json; charset=utf-8',
    success: function(data) {
         $.each(data.pois, function(k, v) {
            L.marker([v[0], v[1]]).addTo(map)
            .bindPopup(v.name)
            .openPopup();
         });
    }
});

//介接經濟部商家查詢api
$.ajax({
   url: "https://egis.moea.gov.tw/MoeaEGFxData_WebAPI_Inside/InnoServe/BusinessBUSM?resptype=GeoJson&x=121.509&y=25.0401&buffer=1000",
   type: 'GET',
   success: function (data) {
       var symbol = {
            radius: 3,
            fillColor: "#ff7800",
            color: "#000",
            weight: 1,
            opacity: 1,
            fillOpacity: 0.8
       };
       L.geoJSON(data, {
            pointToLayer: function (feature, latlng) {
                return L.circleMarker(latlng, symbol);
                }
        }).addTo(map);
    }
});
</script>

server side(ApiController.cs):
API接口取資料庫中的據點資料,假設使用mongodb去Query到bson document..

//取資料接口..
[Route("api/Poi")]
[httpget] 
public JsonResult Poi()
{    
   //Bson collection example [{"name":"市府店","geo":[25.0375,121.5529]},{"name":"西門店","geo":[25.0401,121.509]}....]
   List<PoiDataModel> pois =  List<PoiDataModel>();
   //取資料...
   略..
   return Json(...)
}


//新增資料接口...
[Route("api/Poi")]
[httppost]
public JsonResult GetPois(PoiDataModel poi)
{  
   //新增資料進資料庫...
   略..
}

上面範例,結果如下:
https://ithelp.ithome.com.tw/upload/images/20171221/20107816diTXZdz0nu.jpg


上一篇
[Day 1] WebGIS-資訊時代的地理大發現
下一篇
[Day 3] 談互操作性及Web Map Service 標準
系列文
30天打造我的WebGIS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言