LoginSignup
12
12

More than 5 years have passed since last update.

Google Maps JavaScript API の addGeoJson で読み込んだ GeoJSON を扱う

Last updated at Posted at 2016-08-13

GeoJSON を使うと動的にマップにデータを読むこむといったことができます.Google Maps JavaScript API の addGeoJson で GeoJSON を読み込んだときに,スタイルを適用したり,イベントを追加したりする方法を記事にしたいと思います.

GeoJSON

GeoJSON 自体については,以下のようなページを見れば分かります.
データレイヤ | Google Maps JavaScript API | Google Developers
GeoJSON フォーマット仕様

扱えるデータとしては Point,MultiPoint,LineString,MultiLineString,Polygon,MultiPolygon といったものがあります.Google Maps で扱える Circle,Rectangle はありません(どちらもDB上では Polygon として扱えばいいと思います).

読み込むGeoJSON は以下のようなものです.

GeoJSON
{
    "features": [
        {
            "geometry": {
                "coordinates": [
                    135.04531860352, 
                    34.206123649908
                ], 
                "type": "Point"
            }, 
            "properties": {
                "color": "#00ff00", 
                "type": "point", 
                "description": "cat",
            }, 
            "type": "Feature"
        }, 
         {
            "geometry": {
                "coordinates": [
                    134.98489379883, 
                    34.585736286513
                ], 
                "type": "Point"
            }, 
            "properties": {
                "color": "#ff0000", 
                "type": "point", 
                "description": "dog",
            }, 
            "type": "Feature"
        }, 
        {
            "geometry": {
                "coordinates": [
                    [
                        [
                            135.14419555664, 
                            34.532581106491
                        ], 
                        [
                            135.17852783203, 
                            34.475995767559
                        ], 
                        [
                            135.23208618164, 
                            34.517872614017
                        ], 
                        [
                            135.17990112305, 
                            34.582344417658
                        ], 
                        [
                            135.17303466797, 
                            34.540499988011
                        ], 
                        [
                            135.14419555664, 
                            34.532581106491
                        ]
                    ]
                ], 
                "type": "Polygon"
            }, 
            "properties": {
                "color": "#0000ff", 
                "type": "polygon", 
                "description": "duck",
            }, 
            "type": "Feature"
        }, 
        {
            "geometry": {
                "coordinates": [
                    [
                        134.79537963867, 
                        34.228267666464
                    ], 
                    [
                        134.81048583984, 
                        34.228835385227
                    ], 
                    [
                        134.81254577637, 
                        34.246432768532
                    ], 
                    [
                        134.79537963867, 
                        34.236215380881
                    ]
                ], 
                "type": "LineString"
            }, 
            "properties": {
                "color": "#ff0000", 
                "type": "polyline", 
                "description": "wolf",
            }, 
            "type": "Feature"
        }, 
     ], 
    "type": "FeatureCollection"
}

スタイルの適用

propertiescolor に色を, type に表示するタイプを入れています.GeoJSON のタイプと,色によって表示するスタイルを切り替えます.マーカー,ポリライン,ポリゴンとそれぞれ処理は違いますが,マーカーの場合の処理は関数化させています.

map.data.setStyle でスタイルの定義を行います.feature に各レイヤーのデータが入っていて,feature.getProperty を使ってレイヤーごとのプロパティを取得しています.

(自分は PHP と非同期通信して動的に生成した GeoJSON を表示させています.もちろん,非同期通信ではない場合でも使えます)

JavaScript
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

    // GeoJSON を受け取る
    var geojson = JSON.parse(xmlhttp.responseText);

    // マップに GeoJSON を追加
    // マップにポイントやラインが描画される
    // map は initMap() で定義
    map.data.addGeoJson(geojson);

    // レイヤーのスタイル定義
    map.data.setStyle(function(feature) {
      if (feature.getProperty('type') === 'point') {
        // マーカーの処理は関数を使って処理
        return ({
          icon: getMarkerColor(feature.getProperty('color')),
        }); 
      } else if (feature.getProperty('type') === 'polyline') {
        // ポリラインの処理
        return ({
          strokeColor: feature.getProperty('color'),
          strokeWeight: 2,
          clickable: true,
          zIndex: 1
        });
      } else {
        // ポリゴンの処理
        return ({
          fillColor: feature.getProperty('color'),
          fillOpacity: 0.5,
          strokeWeight: 0,
          clickable: true,
          zIndex: 1
        });
      }
    });
  }
}
xmlhttp.open('POST', 'get_geojson.php', true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.timeout = 10000;
xmlhttp.send(); 
JavaScript
function getMarkerColor(color) {

  switch(color) {
  case '#ff0000':
    markerIcon = 'marker_red.png';
    break;
  case '#00ff00':
    markerIcon = 'marker_green.png';
    break;
  case '#0000ff':
    markerIcon = 'marker_blue.png';
    break;
  }

  return {
    url: './icon/' + markerIcon,
    scaledSize: new google.maps.Size(21, 32),  // scaledSize でリサイズ
  };
}

参考:
Google Maps API Adds GeoJSON Support: Here is an example | Technical Tidbits From Spatial Analysis & Data Science:

イベントの設定

読み込んだレイヤーにイベントを追加したい場合があると思います.今回はレイヤーに対して,インフォウィンドウ(info windows)を追加する処理を書きます.

event.feature でレイヤーと同じように feature を取り出すことができ,プロパティを取得することができます.

JavaScript
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

    // GeoJSON を受け取る
    var geojson = JSON.parse(xmlhttp.responseText);

    // マップに GeoJSON を追加
    // マップにポイントやラインが描画される
    map.data.addGeoJson(geojson);

    // レイヤーのスタイル定義
    ...()

    // ユーザがレイヤーをクリックしたときの処理
    map.data.addListener('click', function(event) {
      // infowindow は initMap() 内で
      // infowindow = new google.maps.InfoWindow(); として定義
      var description = event.feature.getProperty('description'); // infowindow に入れる内容
      infowindow.setContent(description);
      infowindow.setPosition(event.latLng); // ここでinfowindowの位置を指定
      infowindow.setOptions({pixelOffset: new google.maps.Size(0,-30)});
      infowindow.open(map);
    });
  }
}
xmlhttp.open('POST', 'get_geojson.php', true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.timeout = 10000;
xmlhttp.send(); 
12
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
12