Help us understand the problem. What is going on with this article?

Pure CSS で書く地図用マーカー(MapboxGL JS版)

前回の記事で書いたように、A4サイズでいい感じに印刷できる地図サービスを運用中です。

印刷できる台風災害支援情報マップ(千葉県)

スクリーンショット 2019-09-21 13.02.34.png

上のサイトの構築には MapboxGL.js を使っています。
サイトのマーカー部分はCSSと Font Awesome にて実現していますが、CSS のみでマーカーを作る部分は結構ニーズありそうなので、記事に残しておこうと思いました。

もちろん Mapbox Studio でもアイコンを選ぶことができるのですが、種類はあまり多くありません。オリジナルのSVGファイルをアップすることもできるのですが、ちょっと手間ですよね。

MapboxGL.js は、マーカーの中にHTMLエレメントを入れることができるので、そちらでマーカーを配置することにします。

まずは、基本のマーカーから。
以下のような Geojson データを表示するとします。その際、class に marker 要素を持たせた div エレメントを持ったマーカーを作成します。

javascript
mapboxgl.accessToken = 'アクセストークン';
var map = new mapboxgl.Map({
container: 'map',
center: [139.646,35.626],
zoom: 12,
style: 'mapbox://styles/georepublic/cjvw34h830hx01cpgws5f0mpt'
});
// Add pure css marker
var geojson = {
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.640,35.626]
    },
    properties: {
      title: 'Point1',
      number: 1
    }
  },{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.653,35.626]
    },
    properties: {
      title: 'Point2',
      number: 10
    }
  }]
}
// make a marker for each feature and add to the map
geojson.features.forEach(function(marker) {
    // create a HTML element for each feature
    var el = document.createElement('div');
    el.append(document.createElement('span'))
    el.className = 'marker';
    new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
    .addTo(map);
});

次に、marker クラスのスタイルを作成します。

css
.marker {width:0; height:0;}

.marker  span {
  display:flex;
  justify-content:center;
  align-items:center;
  box-sizing:border-box;
  width: 30px;
  height: 30px;
  color:#fff;
  background: #693;
  border:solid 2px;
  border-radius: 0 70% 70%;
  box-shadow:0 0 2px #000;
  cursor: pointer;
  transform-origin:0 0;
  transform: rotateZ(-135deg);
}

このスタイルを適用すると、以下のようなマーカーが表示できます。

スクリーンショット 2019-09-21 22.40.46.png

数字入りアイコン

さらに、以下のように、アイコンの中に数字を入れることもできます。

javascript
var geojson = {
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.75037,35.67087]
    },
    properties: {
      title: 'Georepublic Japan',
      number: 1
    }
  },{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.75237,35.67087]
    },
    properties: {
      title: 'Point2',
      number: 10
    }
  }]
}
geojson.features.forEach(function(marker) {
    // create a HTML element for each feature
    var el = document.createElement('div');
    el.innerHTML = '<span><b class="number">' + marker.properties.number + "</b></span>";
    el.className = 'marker';
    // make a marker for each feature and add to the map
    new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
    .addTo(map);
});
cssに以下を追加
.marker b {transform: rotateZ(135deg)}

スクリーンショット 2019-09-21 22.42.07.png

Font Awesome をアイコンに利用

以下のように Font Awesome をアイコンに使うことも可能です

javascript
// Add pure css marker
var geojson = {
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.75037,35.67087]
    },
    properties: {
      title: 'Georepublic Japan',
      type: 'company'
    }
  },{
    type: 'Feature',
    geometry: {
      type: 'Point',
      coordinates: [139.75237,35.67087]
    },
    properties: {
      title: 'Ramen shop',
      type: 'restaurant'
    }
  }]
}
geojson.features.forEach(function(marker) {
    // create a HTML element for each feature
    var el = document.createElement('div');
    if (marker.properties.type == 'company'){
        el.innerHTML = '<span><i class="fas fa-building"></i></span>';
    }else if(marker.properties.type = 'restaurant'){
        el.innerHTML = '<span><i class="fas fa-utensils"></i></span>';
    }
    el.className = 'marker';
    // make a marker for each feature and add to the map
    new mapboxgl.Marker(el)
    .setLngLat(marker.geometry.coordinates)
    .addTo(map);
});
css
.marker i {transform: rotateZ(135deg)}

スクリーンショット 2019-09-21 23.03.18.png

いかがでしたでしょうか。CSSなので色を変えるのも容易ですし、SVGを用意するよりも手軽に使うことができます。

冒頭の私たちのサイトも、少々複雑ですがCSSとFont Awesome で作られております。

実際に動くサンプルコードは、こちらの GitHub リポジトリ から見ることができます。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away