Google Maps API - 顯示 GeoJSON 資料

透過 Google Maps API 在地圖上繪製圖形不困難,但「取得地圖上的資料」卻令人頭痛,幸好隨著科技的進步,我們可以透過 GeoJSON 這種專門處理地理資訊結構的格式,更方便的在地圖上顯示各種資訊,這篇就來簡單介紹一下 GeoJSON,並在 Google 地圖上顯示對應的樣貌。

GeoJSON 簡介

GeoJSON 是一種對地理資訊結構進行編碼的格式,基於 JavaScript 物件標記的地理空間資訊資料交換格式 ( 所以才會是 Geo + json ),GeoJSON 支援像是點、線、多邊形、多點、多線、多個多邊形的幾何形狀,當中也包含了特徵或特徵的集合資訊。

舉例來說,一個 GeoJSON 最外層包含一個 type 為 FeatureCollection 的屬性,接著 features 的屬性包含了許多 type 為 Feature 的物件,這些 Feature 物件裡包含 properties 的屬性,可以設定區域的顏色、邊框...等樣式,也包含了 geometry 的屬性,定義地圖上形狀的面貌,以下面這段 GeoJSON 來說,就是在台北 101 旁的松壽路上,畫「一段粗細 10px,透明度 0.5 的紅色直線」。

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "stroke": "#ff0000",
        "stroke-width": 10,
        "stroke-opacity": 0.5
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            121.56351685523987,
            25.03585799721269
          ],
          [
            121.56548023223877,
            25.0358093932627
          ]
        ]
      }
    }
  ]
}

Google Maps API - 顯示 GeoJSON 資料

上面的例子中,type 設定為 LineString 呈現的是直線,如果要呈現多邊形,就要將 type 設為 Polygon,下面的 GeoJSON 呈現的是台北 101 被一個「黑色實線、紅色半透明填滿的正方形」圍住。

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "stroke": "#000000",
        "stroke-width": 2,
        "stroke-opacity": 1,
        "fill": "#ff2600",
        "fill-opacity": 0.5
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              121.56345248222352,
              25.03295144714567
            ],
            [
              121.5654158592224,
              25.03295144714567
            ],
            [
              121.5654158592224,
              25.03476926411677
            ],
            [
              121.56345248222352,
              25.03476926411677
            ],
            [
              121.56345248222352,
              25.03295144714567
            ]
          ]
        ]
      }
    }
  ]
}

Google Maps API - 顯示 GeoJSON 資料

產生 GeoJSON

雖然說已經知道了 GeoJSON 的格式,但要產生 GeoJSON 最麻煩的仍然是那些小數點好多位數的「座標」,這時候就要透過 geojson.io 這個線上服務,來幫我們產生標準又漂亮的 GeoJSON。

參考連結:http://geojson.io/

打開網頁後,映入眼簾的是左右兩個視窗,左邊的視窗是地圖,右上角有繪圖的工具,右邊的視窗會根據所繪製的圖案,自動產生 GroJSON。

Google Maps API - 顯示 GeoJSON 資料

用「多邊形」工具把台北 101 旁邊的台北世界貿易中心框起來,就會看到對應的 GeoJSON 自動產生出來。

Google Maps API - 顯示 GeoJSON 資料

用滑鼠點擊畫好的多邊形,就可以修改多邊形的屬性,修改後在 GeoJSON 裡的 properties 也會自動產生,下圖就是把繪製的多邊形,改成黑色外框紅色填滿的屬性。

Google Maps API - 顯示 GeoJSON 資料

透過 geojson.io 這個方便好用的網站,要產生 GeoJSON 已經不再那麼困難,接著就來實作如何用 Google 地圖顯示 GeoJSON 資料。

Google 地圖顯示 GeoJSON 資料

匯入 GeoJSON 資料其實很簡單,每個 Google 地圖都有一個 map.data 物件,做為任意地理空間資料(包括 GeoJSON)的資料圖層,只要呼叫 data 物件的loadGeoJSON()方法就可以,用法如下:

map.data.loadGeoJson('GeoJSON.json');

舉例來說,下面這段程式碼,就會在地圖上載入上面我們所畫好的台北世貿中心。

範例:Google 地圖顯示 GeoJSON 資料

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 17,
    center: {lat: 25.034010, lng:121.562428}
  });

  map.data.loadGeoJson('geojson.demo.json');
}

Google Maps API - 顯示 GeoJSON 資料

不過很神奇的,載入之後我們原本設定的樣式反而不見了,這時候就得使用Data.setStyle()方法來指定資料外觀,以剛剛的例子來說,只要改寫成下面這樣,就能讓原本的形狀多了些色彩。

範例:Google 地圖顯示 GeoJSON 資料 - 改變樣式 1

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 17,
    center: {lat: 25.034010, lng:121.562428}
  });

  map.data.loadGeoJson('geojson.demo.json');

  map.data.setStyle({
    strokeWeight: 20,
    strokeOpacity: .5,
    strokeColor: '#f00',
    fillColor: '#0c0',
    fillOpacity: .35
  });
}

Google Maps API - 顯示 GeoJSON 資料

如果還是想使用我們自定義的 GeoJSON 樣式該怎麼做呢?這時就得用到map.data.setStyle(function(feature)){}來取的每筆資料的屬性,下面的例子將會把我們自定義的 properties 的樣式取出,套用到 Google 地圖上。

範例:Google 地圖顯示 GeoJSON 資料 - 改變樣式 2

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 17,
    center: {lat: 25.034010, lng:121.562428}
  });

  map.data.loadGeoJson('geojson.demo.json');

  map.data.setStyle(function(feature){
    return {
      strokeWeight: feature.getProperty('stroke-width'),
      strokeOpacity: feature.getProperty('stroke-opacity'),
      strokeColor: feature.getProperty('stroke'),
      fillColor: feature.getProperty('fill'),
      fillOpacity: feature.getProperty('fill-opacity')
    }
  });
}

Google Maps API - 顯示 GeoJSON 資料

同樣道理,如果我們手動在 properties 內定義一個名為 name 的屬性,就可以在「多個形狀」的資料下,指定每筆資料產生的形狀樣式,以下面的例子來說,透過 name 的屬性,就能指定紅色和綠色的區塊按照 GeoJSON 的配置顯示色彩,而另外一個區塊就用預設的 Google 形狀來顯示。

範例:Google 地圖顯示 GeoJSON 資料 - 多個形狀

var map;
function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 17,
    center: {lat: 25.034010, lng:121.562428}
  });

  map.data.loadGeoJson('geojson.demo2.json');

  map.data.setStyle(function(feature){
    if(feature.getProperty('name')=='red' || feature.getProperty('name')=='green'){
      return {
        strokeWeight: feature.getProperty('stroke-width'),
        strokeOpacity: feature.getProperty('stroke-opacity'),
        strokeColor: feature.getProperty('stroke'),
        fillColor: feature.getProperty('fill'),
        fillOpacity: feature.getProperty('fill-opacity')
      }
    }
  });
}

Google Maps API - 顯示 GeoJSON 資料

小結

基本上透過 Google 地圖來顯示 GeoJSON 資料沒有太大的難度,比較難的是讀取資料後要怎麼用視覺化呈現,讓使用者可以一目瞭然,接下來會再嘗試讀取資料後再做一些變化,敬請期待囉~ ^_^

參考

有興趣瞧瞧其他新文章嗎?