LoginSignup
2
2

More than 5 years have passed since last update.

ElectronでOpenLayers3を使ってみる。(その1)

Last updated at Posted at 2016-10-29

ElectronでOpenLayers3を使ってみる。(その1)

タイトルの通りです。地形データを使ったアプリケーションを作る必要があるのですが、面倒なことはやりたくないので、便利なものは使わせてもらう方向で勉強中です。
なので、以降で掲示したソースも、まだ様々なサンプルの張り合わせです。徐々に自分の書いた箇所が増えていけば良いな。

ソフト等 バージョン 備考
Electron V1.4.4 Electron公式
OpenLayers3 v3.19.1 Openlayers3公式
国土地理院タイル 色別標高図 地理院タイル一覧

準備

Electronの導入は簡単ですし、Qiitaにも情報は多いので割愛します。Nodeからnpmで入れても、公式から、各OS環境用のzipをダウンロードしてきて解凍しても問題ありません。
任意の場所に、アプリケーション用のフォルダを以下のように作ります。
file.png
なお、olフォルダの中の、ol.cssとol.jsは、OpenLayers3のものです。公式からダウンロードしてきて解凍後、ここに置きました。

package.json

特に説明する必要もありません。nameとlicenseしか触っていません。

package.json
{
  "name": "Map Sample (Powerd by Electron & OpenLayers3)",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "MIT"
}

index.js

Electron関連のjs。今後は、アプリケーションメニューなど変更して行きたいので、Electron-APIの勉強が必要かと思っています。

index.js
'use strict';

// Electronのモジュール
const electron = require("electron");

// アプリケーションをコントロールするモジュール
const app = electron.app;

// ウィンドウを作成するモジュール
const BrowserWindow = electron.BrowserWindow;

// メインウィンドウはGCされないようにグローバル宣言
let mainWindow;

// 全てのウィンドウが閉じたら終了
app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// Electronの初期化完了後に実行
app.on('ready', function() {
  // メイン画面の表示。ウィンドウの幅、高さを指定できる
  mainWindow = new BrowserWindow({width: 800, height: 600});
  mainWindow.loadURL('file://' + __dirname + '/index.html');

  // ウィンドウが閉じられたらアプリも終了
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

index.html

ほぼOpenLayers3のExamplesから切り貼りしただけ。少しコメントを入れてますが、メモとして書いただけです。地図の下にあるformはメニューに入れたいところ。

index.html
<!DOCTYPE html>
<html>
<head>
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta http-equiv="content-style-type" content="text/css">
  <meta http-equiv="content-script-type" content="text/javascript">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- OpenLayers3 参照 -->
  <link rel="stylesheet" href="ext/ol/ol.css" type="text/css">
  <script src="ext/ol/ol.js" type="text/javascript"></script>
<!-- 自作外部ファイル 参照 -->
  <link rel="stylesheet" href="sample.css" type="text/css">
  <script src="sample.js" type="text/javascript"></script>
</head>
<body onload="init_map()">
  <div id="screen_top">
<!-- 地図本体 -->
    <div id="map"></div>
<!-- 地図下部 -->
    <form class="form-inline">
      <label>TypeSelect</label>
      <select id="type">
        <option value="Point">Point</option>
        <option value="LineString">LineString</option>
        <option value="Polygon">Polygon</option>
      </select>
    </form>
<!-- コメント -->
    <hr>
    <pre>
  ドラッグ:地図移動。Shift+ALT+ドラッグ:地図回転。Shift+ドラッグ:選択範囲を拡大。Ctrl+ホイール:拡大縮小。
  Point:クリックで点を追加。既存の点やラインをドラッグすると移動。Shift+既存の点をクリックで削除。
  LineString:クリックで連続線を追加。ダブルクリックで終点を追加。
  Polygon:クリックで連続線を追加。始点を選んでクリックするか、ダブルクリックで始点まで閉じる。
    </pre>
  </div>
</body>
</html>

sample.css

ほぼ、参考にさせていただいたサイトのソースのままです。

sample.css
div.fill {width: 100%; height: 100%;}
body {width: inherit; height:inherit; padding: 0; margin: 0}
html, body, #map {height: 100%; width: 100%;}

.ol-attribution {
  padding: 3px;  position: absolute;  background-color:#ffffff;
  background-color:rgba(230,255,255,0.7);
  right: 3px;  bottom:5px;  font-size:12px;
}
.ol-attribution ul { padding: 0px;  line-height: 14px;  margin: 0px; }
.ol-attribution li { line-height: inherit;  display: inline;  list-style: none outside none; }

.ol-zoom .ol-zoom-out { margin-top: 202px; }
.ol-zoomslider { background-color: transparent; top: 2.3em; }
.ol-touch .ol-zoom .ol-zoom-out { margin-top: 212px; }
.ol-touch .ol-zoomslider { top: 2.75em; }

sample.js

参考にさせていただいたサイトのソースに、OpenLayers3のExamplesから切り貼りして、細部を好みで直した程度です。

sample.js
// ===================================================================
var center_lon = 136.881505; // 中心の経度
var center_lat = 35.171130;  // 中心の緯度

var initZoom = 8;   // ズームの初期値
var MinZoom  = 6;   // ズームの最小値(最も広い範囲)
var MaxZoom  = 17;  // ズームの最大値(最も狭い範囲)
// *******************************************************************
function init_map() {
// 表示用の view 変数の定義。
    var view = new ol.View({
        projection: "EPSG:3857",
        maxZoom: MaxZoom,
        minZoom: MinZoom
    })

// layer(地理院地図の色別標高図)用の変数
    var lay = new ol.layer.Tile({
        source: new ol.source.XYZ({
            attributions: [ new ol.Attribution({
              html: "<a href='http://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>"
            }) ],
            url: "http://cyberjapandata.gsi.go.jp/xyz/relief/{z}/{x}/{y}.png",
            projection: "EPSG:3857"
        })
    })

// 地図変数 (map 変数) の定義。地理院地図を表示するように指定している。
    var map = new ol.Map({
        target: document.getElementById('map'),
        layers: [lay],
        view: view,
        renderer: ['canvas', 'dom'],
        controls: ol.control.defaults().extend([new ol.control.ScaleLine()]),
        interactions: ol.interaction.defaults()
    });

// zoom slider の追加
    map.addControl(new ol.control.ZoomSlider());

// 中心の指定。view に対して指定。transform を忘れないこと。
    view.setCenter(ol.proj.transform([center_lon, center_lat], "EPSG:4326", "EPSG:3857"));

// zoom の指定。view に対して指定する。
    view.setZoom(initZoom);

// 各ベクター等のスタイル
    var features = new ol.Collection();
    var featureOverlay = new ol.layer.Vector({
      source: new ol.source.Vector({features: features}),
      style: new ol.style.Style({
        fill: new ol.style.Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new ol.style.Stroke({
          color: '#ff3333',
          width: 3
        }),
        image: new ol.style.Circle({
          radius: 5,
          fill: new ol.style.Fill({
            color: '#ff3333'
          })
        })
      })
    });
    featureOverlay.setMap(map);

    var modify = new ol.interaction.Modify({
      features: features,
      // the SHIFT key must be pressed to delete vertices, so
      // that new vertices can be drawn at the same position
      // of existing vertices
      deleteCondition: function(event) {
        return ol.events.condition.shiftKeyOnly(event) &&
            ol.events.condition.singleClick(event);
      }
    });
    map.addInteraction(modify);

    var draw; // global so we can remove it later
    var typeSelect = document.getElementById('type');

    function addInteraction() {
      draw = new ol.interaction.Draw({
        features: features,
        type: /** @type {ol.geom.GeometryType} */ (typeSelect.value)
      });
      map.addInteraction(draw);
    }


    /**
     * Handle change event.
     */
    typeSelect.onchange = function() {
      map.removeInteraction(draw);
      addInteraction();
    };

    addInteraction();

}

画面イメージ

現在の画面イメージは次のような感じ。
地図上に点や線がおけるようになりました。
今後は、座標を使って色々な処理ができるようにしていく予定。

sample.png

2
2
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
2
2