Movable TypeでLeaflet MAP座標のコンテンツタイプ追加してみた。

らら
らら

はじめに

今回は、前回作成した、「Movable TypeでGoogleMAP座標のコンテンツタイプ追加してみた。」のバージョンアップです。

GoogleMAPとLeaflet(OpenStreetMap)の両方を対応できるようにしました。

座標選択を、GoogleMAPとLeaflet(OpenStreetMap)を選択できる感じなります。

2025年3月からGoogleMAPの無料枠なくなったので、とりあえず。

関連

Movable TypeでGoogleMAP座標のコンテンツタイプ追加してみた。
https://www.omakase.net/blog/2024/06/movable-typegooglemap.html

ディレクリ構造


ContentMapCoordtField
│  config.yaml
├─lib
│  │  ContentMapCoordtField.pm
│  └─ContentMapCoordtField
│	  │  App.pm
│	  └─ContentFieldType
│			  ContentMapCoordtField.pm
│
└─tmpl
	│  config.tmpl
	│  selectmap_googlemap.tmpl
	│  selectmap_leaflet.tmpl
	├─content_field_type_options
	│	  googlemap_coordinate.tmpl
	│	  map_coordinate.tmpl
	└─field_html
			field_html_map_coordinate.tmpl

config.yaml

前回のものと互換のためgooglemap_coordinateとmap_coordinateの2つあります。

新規で利用する場合は、googlemap_coordinateは不要です。

あとGooglemapとあったものを省いています。


id: ContentMapCoordtField
name: ContentMapCoordtField
version: 2.0
author_name: 
author_link: 
description: <__trans phrase="This plugin adds a GoogleMap coordinate content field type.">
l10n_lexicon:
    ja:
        This plugin adds a GoogleMap coordinate content field type.: "GoogleMap座標コンテンツフィールドを追加"
        Map System: 使用するマップシステム
        Map Coordinate: Map座標
        GoogleMap Coordinate: GoogleMap座標
        Google Maps API key: Google Maps API key
        Google Maps API ID: Google Maps ID
        Maps latitude : 緯度(lat)
        Maps longitude : 経度(lng)
        Google Maps latitude : 緯度(lat)
        Google Maps longitude : 経度(lng)
        Maps Default Latitude : 地図中心緯度(lat)
        Maps Default Longitude : 地図中心 経度(lng)
applications:
    cms:
        methods:
            map_popup: ContentMapCoordtField::App::map_popup
tags:
    function:
        GoogleMapKey:       $ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_key
        GoogleMapId:        $ContentMapCoordtField::ContentMapCoordtField::_hdlr_googlemap_id
        MapLatitude:  $ContentMapCoordtField::ContentMapCoordtField::_hdlr_map_latitude
        MapLongitude: $ContentMapCoordtField::ContentMapCoordtField::_hdlr_map_longitude
        GoogleMapLatitude:  $ContentMapCoordtField::ContentMapCoordtField::_hdlr_map_latitude
        GoogleMapLongitude: $ContentMapCoordtField::ContentMapCoordtField::_hdlr_map_longitude
content_field_types:
    map_coordinate:
        label: Map Coordinate
        data_type: 'text'
        order: 301,
        icon_class: 'ic_singleline'
        can_data_label_field: 0
        data_load_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::data_load_handler
        field_value_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_value_handler
        field_html: 'field_html/field_html_map_coordinate.tmpl'
        field_html_params: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_html_params
        list_props:
            map_coordinate:
                base: '__virtual.string'
                col: 'value_varchar'
                terms: $Core::MT::ContentFieldType::Common::terms_text
        options_html: 'content_field_type_options/map_coordinate.tmpl'
        options:
            - label
            - description
            - required
            - display
            - initial_value
    googlemap_coordinate:
        label: GoogleMap Coordinate
        data_type: 'text'
        order: 300,
        icon_class: 'ic_singleline'
        can_data_label_field: 0
        data_load_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::data_load_handler
        field_value_handler: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_value_handler
        field_html: 'field_html/field_html_map_coordinate.tmpl'
        field_html_params: $ContentMapCoordtField::ContentMapCoordtField::ContentFieldType::ContentMapCoordtField::field_html_params
        list_props:
            googlemap_coordinate:
                base: '__virtual.string'
                col: 'value_varchar'
                terms: $Core::MT::ContentFieldType::Common::terms_text
        options_html: 'content_field_type_options/googlemap_coordinate.tmpl'
        options:
            - label
            - description
            - required
            - display
            - initial_value
settings:
    maps_system:
        default:
    googlemaps_api_key:
        default:
    googlemaps_id:
        default:
    maps_def_latitude:
        default:
    maps_def_longitude:
        default:
system_config_template: config.tmpl

lib\ContentMapCoordtField.pm


package ContentMapCoordtField;
use strict;
use utf8;
use warnings;
# use Data::Dumper;
my $PluginKey = 'ContentMapCoordtField';
sub instance {
    my ($app) = @_;
    $app ||= 'MT';
    $app->component($PluginKey);
}
#<$MTGoogleMapKey$>
sub _hdlr_googlemap_key {
    my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_api_key');
}
#<$MTGoogleMapID$>
sub _hdlr_googlemap_id {
    my $plugin  = instance();
	return $plugin->get_config_value('googlemaps_id');
}
#<$MTGoogleMapLatitude$>
#<$MTMapLatitude$>
sub _hdlr_map_latitude {
    my $plugin  = instance();
	return $plugin->get_config_value('maps_def_latitude');
}
#<$MTGoogleMapLongitude$>
#<$MTMapLongitude$>
sub _hdlr_map_longitude {
	my $plugin  = instance();
	return $plugin->get_config_value('maps_def_longitude');
}
1;

lib\ContentMapCoordtField\App.pm


package ContentMapCoordtField::App;
use strict;
use File::Basename;
my $PluginKey = 'ContentMapCoordtField';
sub instance {
    my ($app) = @_;
    $app ||= 'MT';
    $app->component($PluginKey);
}
sub map_popup {
	my $app = shift;
	my $param = {};
	my $q	= $app->param;
	my $lat	= $q->param('lat');
	my $lng	= $q->param('lng');
	my $lat_id	= $q->param('lat_id');
	my $lng_id	= $q->param('lng_id');
	my $plugin  = instance();
	my $maps_system			= $plugin->get_config_value('maps_system');
	my $googlemaps_api_key	= $plugin->get_config_value('googlemaps_api_key');
	my $maps_def_latitude	= $plugin->get_config_value('maps_def_latitude');
	my $maps_def_longitude	= $plugin->get_config_value('maps_def_longitude');
	my $website_terms = undef;
	if (my $blog_id = $app->param('blog_id')) {
		$website_terms = { 'id' => $blog_id };
	}
	$param->{lat}						= $lat;
	$param->{lng}						= $lng;
	$param->{lat_id}					= $lat_id;
	$param->{lng_id}					= $lng_id;
	$param->{googlemaps_api_key}		= $googlemaps_api_key;
	$param->{maps_def_latitude}			= $maps_def_latitude;
	$param->{maps_def_longitude}		= $maps_def_longitude;
	my $plugin = MT->component('ContentMapCoordtField');
	if($maps_system eq "GoogleMap") {
		$plugin->load_tmpl('selectmap_googlemap.tmpl', $param);
	} else {
		$plugin->load_tmpl('selectmap_leaflet.tmpl', $param);
	}
}
1;

lib\ContentMapCoordtField\ContentFieldType\ContentMapCoordtField.pm


package ContentMapCoordtField::ContentFieldType::ContentMapCoordtField;
use strict;
use warnings;
sub field_html_params {
    my ( $app, $field_data ) = @_;
    my ( $lat, $lng );
    my $value = $field_data->{value} || '';
    # for initial_value.
    $value = '' unless defined $value;
    $lat = '';
    $lng = '';
    if ( defined $value && $value ne '' ) {
        ( $lat, $lng )    = split ', ', $value;
    }
    my $required = $field_data->{options}{required} ? 'required' : '';
    {    map_coordinate_data => $value,
         lat => $lat,
         lng => $lng,
         required => $required,
    };
}
sub data_load_handler {
    my ( $app, $field_data ) = @_;
    my $id   = $field_data->{id};
    my ( $lat, $lng );
#    $lat = '';
#    $lng = '';
   $lat = $app->param( 'lat-' . $id );
   $lng = $app->param( 'lng-' . $id );
   my $coordinate = $lat .", ". $lng;
   return $coordinate;
}
sub field_value_handler {
    my ( $ctx, $args, $cond, $field_data, $value ) = @_;
    my $coordinate = lc $args->{coordinate} || 'lng';
    my ( $lat, $lng );
    return if ( $coordinate ne 'lat' and $coordinate ne 'lng' );
    ( $lat, $lng )    = split ', ', $value;
    if($coordinate eq 'lat') {
        return $lat;
    }elsif ($coordinate eq 'lng') {
        return $lng;
    } else {
        return $value;
    }
}
1;

tmpl\config.tmpl


<mtapp:setting
  id="contentmapcoordtfield-template_type"
  label="<__trans phrase="Map Coordinate">">
<br />
<mt:var name="maps_system">
  <label for="contentmapcoordtfield-mapsystem"><__trans phrase="Map System"></label><br />
  <input type="radio" id="maps_system_0" name="maps_system" value="GoogleMap" <mt:if name="maps_system" eq="GoogleMap">checked="checked"</mt:if> /> <label for="maps_system_0">GoogleMap</label><br />
  <input type="radio" id="maps_system_1" name="maps_system" value="Leaflet" <mt:if name="maps_system" eq="Leaflet">checked="checked"</mt:if> /> <label for="maps_system_1">Leaflet</label><br />
  <label for="contentmapcoordtfield-googlemaps_api_key"><__trans phrase="Google Maps API key"></label>
  <input type="text" name="googlemaps_api_key" id="contentmapcoordtfield-googlemaps_api_key" class="form-control w-100" value="<mt:var name="googlemaps_api_key" escape="html">">
  <label for="contentmapcoordtfield-def_latitude"><__trans phrase="Google Maps ID"></label>
  <input type="text" name="googlemaps_id" id="contentmapcoordtfield-googlemaps_id" class="form-control w-100" value="<mt:var name="googlemaps_id" escape="html">">
  <label for="contentmapcoordtfield-def_latitude"><__trans phrase="Maps Default Latitude"></label>
  <input type="text" name="maps_def_latitude" id="contentmapcoordtfield-maps_def_latitude" class="form-control w-100" value="<mt:var name="maps_def_latitude" escape="html">">
  <label for="contentmapcoordtfield-def_longitude"><__trans phrase="Maps Default Longitude"></label>
  <input type="text" name="maps_def_longitude" id="contentmapcoordtfield-maps_def_longitude" class="form-control w-100" value="<mt:var name="maps_def_longitude" escape="html">">
</mtapp:setting>

tmpl\selectmap_googlemap.tmpl


<!DOCTYPE html>
<html lang="ja" itemscope itemtype="http://schema.org/WebPage">
<head>
<meta charset="UTF-8">
<title>経度・緯度</title>
<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=true&key=<mt:var name="googlemaps_api_key">"></script>
<script type="text/javascript">
function value_set(lat,lng){
	if(!lat && !lng) {
		return [<mt:var name="maps_def_latitude">,<mt:var name="maps_def_longitude">];
	}
	return [lat,lng]
}
	var Lat_id			= "<mt:var name="lat_id">";
	var Lng_id			= "<mt:var name="lng_id">";
	var Lat				= "<mt:var name="lat">";
	var Lng				= "<mt:var name="lng">";
	var latlon;
	latlon = value_set(Lat,Lng);
	// 初期設定項目
	var initLat			= latlon[0];
	var initLng			= latlon[1];		// 初期表示する経度
	var crossSize		= 19;				// クロスの長さ
	var zoomLevelMin	= 0;				// ズームレベルの最大値
	var zoomLevelMax	= 21;				// ズームレベルの最小値
	var	zoomLevelInit	= 18;				// ズームレベルの初期表示値
	var mapOptions = {						// mapオプション
		zoom: zoomLevelInit,
		center: new google.maps.LatLng(initLat,initLng),
		navigationControl: true,
		scaleControl: true,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	// 初期設定項目終了
	// 使用オブジェクト
	var map;								// gmapオブジェクト
	var controlCross;						// センターに表示するクロス
	var lat		= 0;						// 緯度保持
	var lng		= 0;						// 経度保持
	var geocoder;							// ジオコーダー
	/**************************************************************************/
	/*Google Map 作成
	***************************************************************************/
	function createGmap()
	{
		geocoder = new google.maps.Geocoder();
		map = new google.maps.Map(document.getElementById("gmap"),mapOptions);
		// 中心マーカーの表示
		createCenterMaker();
		// イベントリスナーの登録
		google.maps.event.addListener(map,'center_changed',OnMapDraged);			// ドラッグ終了
		OnMapDrag();
	}
	/**************************************************************************/
	/* センターマーカーオブジェクト
	***************************************************************************/
	function CrossControl(controlDiv, map)
	{
		var mapDiv = map.getDiv();
		var x = (mapDiv.offsetWidth  - crossSize + 1) / 2;
		var y = (mapDiv.offsetHeight - crossSize + 1) / 2;
		var controlCrossV = document.createElement('DIV');
		controlCrossV.style.position = 'absolute'
		controlCrossV.style.borderStyle = 'none none none solid';
		controlCrossV.style.borderWidth = '1px';
		controlCrossV.style.borderColor = 'red';
		controlCrossV.style.height = crossSize + 'px';
//		controlCrossV.style.posLeft = 0;
//		controlCrossV.style.posTop = y;
		controlCrossV.style.left = 0+ "px";
		controlCrossV.style.top = y+ "px";
		controlDiv.appendChild(controlCrossV);
		var controlCrossH = document.createElement('DIV');
		controlCrossH.style.position	= 'absolute'
		controlCrossH.style.borderStyle = 'solid none none none';
		controlCrossH.style.borderWidth = '1px';
		controlCrossH.style.borderColor = 'red';
		controlCrossH.style.width		= crossSize + 'px';
//		controlCrossH.style.posLeft		= (crossSize / 2) * -1;
//		controlCrossH.style.posTop = mapDiv.offsetHeight / 2;
		controlCrossH.style.left		= (crossSize / 2) * -1+ "px";
		controlCrossH.style.top = mapDiv.offsetHeight / 2+ "px"; 
		controlDiv.appendChild(controlCrossH);
	}
	/**************************************************************************/
	/* センターマーカー作成
	***************************************************************************/
	function createCenterMaker() {
		var CrossControlDiv = document.createElement('DIV');
		var crossControl	= new CrossControl(CrossControlDiv,map);
		CrossControlDiv.index = 1;
		map.controls[google.maps.ControlPosition.TOP].push(CrossControlDiv);
	}
	/**************************************************************************/
	/* 表示位置移動
	*	画面上の座標に表示された位置へ移動
	***************************************************************************/
	function moveMap()
	{
		lng = parseFloat(document.points.lng.value);
		lat = parseFloat(document.points.lat.value);
		map.panTo(new google.maps.LatLng(lat,lng));
	}
	/**************************************************************************/
	/* 地図ドラッグ(地図)
	***************************************************************************/
	function OnMapDrag()
	{
		latlng = map.getCenter();
		document.points.lng.value = latlng.lng();
		document.points.lat.value = latlng.lat();
	}
	/**************************************************************************/
	/* 地図ドラッグ終了(地図)
	***************************************************************************/
	function OnMapDraged()
	{
		OnMapDrag();
	}
function popup_end(lng,lat)
{
	opener.document.getElementById(Lat_id).value = lat;
	opener.document.getElementById(Lng_id).value = lng;
	window.close();
}
</script>
</head>
<body onload="createGmap()">
<div id="gmap" style="width: 500px; height: 400px"></div>
<br />
<form name="points"  method="post" action="">
	<input type="text" id="lat" name="lat" size="31" maxlength="20">
	<input type="text" id="lng" name="lng" size="32" maxlength="20">
	<br />
	<input type="hidden" name="url" value="">
	<input type="hidden" name="lat_tky" value="">
	<input type="hidden" name="lon_tky" value="">
	<input type="button" value="決定" onclick="popup_end(this.form.lng.value,this.form.lat.value)">
	</font>
</form>
</body>
</html>

tmpl\selectmap.tmpl


<!DOCTYPE html>
<html lang="ja" itemscope itemtype="http://schema.org/WebPage">
<head>
<meta charset="UTF-8">
<title>経度・緯度</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
	var Lat_id			= "<mt:var name="lat_id">";
	var Lng_id			= "<mt:var name="lng_id">";
	var Lat				= "<mt:var name="lat">";
	var Lng				= "<mt:var name="lng">";
$(function(){
	function value_set(lat,lng){
		if(!lat && !lng) {
			return [<mt:var name="maps_def_latitude">,<mt:var name="maps_def_longitude">];
		}
		return [lat,lng]
	}
	function addOnload(evtFunc){
		if(window.addEventListener) {
			window.addEventListener('load', evtFunc, false);
		} else if(window.attachEvent){ //IE用
			window.attachEvent('onload', evtFunc);
		} else {
			//alert('window.onload エラー');
		}
	}
	var mymap;
	addOnload(function(){
		mymap = L.map('map'); 
		L.tileLayer('https://c.tile.openstreetmap.org/{z}/{x}/{y}.png', {
			maxZoom: 18,
			attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a> contributors, '
		}).addTo(mymap);
		var latlon;
		latlon = value_set(Lat,Lng);
		// 初期設定項目
		var initLat			= latlon[0];
		var initLng			= latlon[1];		// 初期表示する経度
		mymap.setView([initLat,initLng], 16);
		//最初の値を出力
		outputPos(mymap); 
		var crossIcon = L.icon({ //センタークロス表示用
			iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAAXNSR0IArs4c6QAAAEBJREFUOE9jZCACvJVR+S/85A4jIaUEFYAMGDUMJRhHwwwRHEQnDZBCQomRWPnRCCAjAogJXKJjc9QweAgQG2YABnRKQFk5giQAAAAASUVORK5CYII=",
			iconSize: [19, 19],
			iconAnchor: [16, 16]
		});
		var crossMarker = L.marker( mymap.getCenter(),{icon:crossIcon,zIndexOffset:1000,interactive:false} ).addTo(mymap);
		//マップムーブイベント
		mymap.on('move', function(e) {
			crossMarker.setLatLng(mymap.getCenter()); //センタークロス表示用
			//マップムーブイベントで値を出力
			outputPos(mymap);
		});
	});
	//現在の緯度・経度・倍率を取得して指定の要素に情報を出力する関数
	function outputPos(map){
		var pos = map.getCenter();
		var zoom = map.getZoom();
		document.getElementById('lat').value = pos.lat;
		document.getElementById('lng').value = pos.lng;
	}
});
function popup_end(lng,lat)
{
	opener.document.getElementById(Lat_id).value = lat;
	opener.document.getElementById(Lng_id).value = lng;
	window.close();
}
</script>
</head>
<body>
<div id="map" style="width: 500px; height: 400px"></div>
<br />
<form name="points"  method="post" action="">
	<input type="text" id="lat" name="lat" size="31" maxlength="20">
	<input type="text" id="lng" name="lng" size="32" maxlength="20">
	<br />
	<input type="hidden" name="url" value="">
	<input type="hidden" name="lat_tky" value="">
	<input type="hidden" name="lon_tky" value="">
	<input type="button" value="決定" onclick="popup_end(this.form.lng.value,this.form.lat.value)">
	</font>
</form>
</body>
</html>

tmpl\content_field_type_options\googlemap_coordinate.tmpl


<mt:app:ContentFieldOptionGroup
   type="googlemap_coordinate">
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lat"
     label="<__trans phrase="Google Maps latitude">">
    <input ref="initial_lat" type="text" name="initial_lat" id="googlemap-coordinate-initial_date" class="form-control date-field w-25" value={ options.initial_lat } placeholder="">
  </mtapp:ContentFieldOption>
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lng"
     label="<__trans phrase=" oogle Maps longitude">">
    <input ref="initial_lng" type="text" name="initial_lng" id="googlemap-coordinate-initial_time" class="form-control time-field w-25" value={ options.initial_lng } placeholder="">
  </mtapp:ContentFieldOption>
</mt:app:ContentFieldOptionGroup>

tmpl\content_field_type_options\map_coordinate.tmpl


<mt:app:ContentFieldOptionGroup
   type="map_coordinate">
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lat"
     label="<__trans phrase="Maps latitude">">
    <input ref="initial_lat" type="text" name="initial_lat" id="googlemap-coordinate-initial_date" class="form-control date-field w-25" value={ options.initial_lat } placeholder="">
  </mtapp:ContentFieldOption>
  <mtapp:ContentFieldOption
     id="googlemap-coordinate-initial-lng"
     label="<__trans phrase="Maps longitude">">
    <input ref="initial_lng" type="text" name="initial_lng" id="googlemap-coordinate-initial_time" class="form-control time-field w-25" value={ options.initial_lng } placeholder="">
  </mtapp:ContentFieldOption>
</mt:app:ContentFieldOptionGroup>

tmpl\field_html\field_html_map_coordinate.tmpl


<div class="row form-inline googlemap-coordinate-field-container group-container">
	<div class="col d-none d-md-block mb-0">
		<span>
			<input type="text" name="lat-<mt:var name="content_field_id" escape="html">" id="lat-<mt:var name="content_field_id" escape="html">" class="lat-field form-control text group html5-form content-field" value="<mt:var name="lat" escape="html">" placeholder="" mt:watch-change="1" mt:raw-name="1" <mt:var name="required">>
		</span>
		<span class="separator"> <__trans phrase=", "></span>
		<span>
			<input type="text" name="lng-<mt:var name="content_field_id" escape="html">" id="lng-<mt:var name="content_field_id" escape="html">" class="lng-field form-control text group html5-form content-field" value="<mt:var name="lng" escape="html">" placeholder="" mt:watch-change="1" mt:raw-name="1" <mt:var name="required">>
		</span>
		<div class="mt-3">
			<a id="mappopup_<mt:var name="content_field_id" escape="html">">
			<svg role="img" class="mt-icon--primary mt-icon--sm first-child last-child"><title class="first-child">Add</title><use xlink:href="/test_mt/mt/mt-static/images/sprite.svg#ic_add" class="last-child"></use></svg>
			座標選択
			</a>
		</div>
	</div>
</div>
<mt:setvarblock name="jq_js_include" append="1">
	$(document).on("click", "[id^=mappopup_]", function(){
		var id_str = $(this).attr("id");
		stArray = id_str.split("_");
		var id_lat = "lat-"+stArray[1];
		var id_lng = "lng-"+stArray[1];
		var lat = $('#'+id_lat).val();
		var lng = $('#'+id_lng).val();
		var url ='<mt:var name="script_url">?__mode=map_popup&lat_id=' + id_lat + '&lng_id=' + id_lng + '&lat=' + lat + '&lng=' + lng;
		win = window.open(url,"map_win","toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=600,height=600");
	});
</mt:setvarblock>

完成のイメージ

プラグイン

Movable Type Leaflet_MAP座標

プラグインの設定

Movable Type Leaflet_MAP座標 Movable Type Leaflet_MAP座標

ContentMapCoordtFieldでできたMTタグ

プラグインの設定で設定した値を取得できます。

MTMapLatitude、MTMapLongitudeは地図の中心座標です。地図選択POPUP等でも使用しています、


<$MTGoogleMapId$>
<$MTGoogleMapKey$>
<$MTMapLatitude$>
<$MTMapLongitude$>
<$MTGoogleMapLatitude$>
<$MTGoogleMapLongitude$>

ContentFieldValue

こちらは、前回と同じ・・

coordinate要素 指定なしは、35.16991042521872, 136.90756276140058で出力されます。

lat指定で35.16991042521872

lng指定で136.90756276140058


<mt:ContentFieldValue coordinate="lat">		緯度
<mt:ContentFieldValue coordinate="lng">		経度

インデックステンプレートで下記を記述して

mapdata.jsで作成します。


<mt:Unless name="blanklinedel" regex_replace="/^[\s\t]*\n/gm","">
const properties = [
<mt:Contents content_type="施設登録">
<mt:ContentField content_field="Googlemap座標">
<mt:ContentFieldValue coordinate="lat" setvar="val">
<mt:If name="val" ne="">
	{
		address: "<mt:ContentField content_field="所在地"><mt:ContentFieldValue></mt:ContentField>",
		description: "<mt:ContentField content_field="施設名"><mt:ContentFieldValue></mt:ContentField>",
		img: "<mt:ContentField content_field="画像"><$mt:AssetURL$></mt:ContentField>",
		type: "<mt:ContentField content_field="施設ランドマーク"><mt:ContentFieldValue></mt:ContentField>",
		url : "<mt:ContentPermalink>",
		position: {
			lat: <mt:ContentFieldValue coordinate="lat">,
			lng: <mt:ContentField content_field="map座標"><mt:ContentFieldValue coordinate="lng"></mt:ContentField>,
		},
	},
</mt:If>
</mt:ContentField>
</mt:Contents>
];
</mt:Unless>

アイコン表示用のHTML

下記HTMLは、MTからの出力を想定しています。MTがあります。

leafletの拡張プラグインleaflet.extra-markersを使用しています。


<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>地図表示</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1">
	<meta name="format-detection" content="telephone=no">
	<meta name="keywords" content=",,,,">
	<meta name="description" content="">
	<meta name="author" content="">
	<meta name="google-site-verification" content="">
<link rel="stylesheet" href="common/css/base.css">
<link rel="stylesheet" href="common/css/top.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<$mt:Date format="%Y%m%d"$ setvar="nowdate">
<script src="mapdata.js?<mt:Var name="nowdate">"></script>
<link rel="stylesheet" href="dist/css/leaflet.extra-markers.min.css">
<script src="dist/js/leaflet.extra-markers.min.js"></script>
<script>
$(function(){
	var map;
	viewMap();
	function	viewMap() {
		var mapData	= {
			pos: { lat: <$MTMapLatitude$>, lng: <$MTMapLongitude$> },
			zoom: 13,
			fitBounds: false
		};
		map = L.map('map').setView(
			[mapData.pos.lat, mapData.pos.lng],
			mapData.zoom
		);
		L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map);
		var i=0;
		for (var property of properties) {
			var color = "";
			if(property.type  == "restroom") {
				color = "cyan";
			} else if(property.type  == "home") {
				color = "red";
			} else {
				color = "orange";
			}
			var icon = L.ExtraMarkers.icon({
				icon: 'fa-' + property.type,
				markerColor: color,
				shape: 'circle',
				prefix: 'fa fa-icon'
			});
			var marker = L.marker(
				[property.position.lat, property.position.lng], 
				{icon: icon},
				{ title: property.description }
			);
			marker.on('click', function() {
				var popup = L.popup();
				if(popup.isOpen) {
					marker.closePopup();
				}else {
					marker.openPopup();
				}
			});
			marker.addTo(map);
			var cont =  buildContent(property);
			if( cont ){
				marker.bindPopup(cont);
			}
			if(!i){
				var bounds = L.latLngBounds([property.position.lat, property.position.lng]);
			}
			bounds.extend( [property.position.lat, property.position.lng] );
			i++;
		}
		if(mapData.fitBounds){
			map.fitBounds( bounds );
		}
		function buildContent(property) {
			const content = document.createElement("div");
			content.className = 'highlight';
			var  imgtag ="";
			if(property.img !="") {
				imgtag 	= `<img src="${property.img}" width="100px">`;
			}
			var  urltag ="";
			if(property.url != undefined) {
				if(property.type != "restroom") {
				 	urltag = `
					<div class="features">
						<div>
							<a href="${property.url}">詳細ページへ</a>
						</div>
					</div>
		 `;
				}
			}
			content.classList.add("property");
			content.innerHTML = `
				<div class="icon">
					<i aria-hidden="true" class="fa fa-icon fa-${property.type}" title="${property.type}"></i>
					<span class="fa-sr-only">${property.type}</span>
				</div>
				<div class="details">
					<div>${imgtag}</div>
					<div class="description">${property.description}</div>
					<div class="address">${property.address}</div>
					${urltag}
				</div>
				`;
			return content;
		}
	}
});
</script>
<style>
#map { width: 900px; height: 400px; }
</style>
</head>
<body>
	<div class="Goforastroll_map_area">
		<div id="map"></div>
	</div>
</body>
</html>

Movable Type Leaflet_MAP座標

さいごに

社内用です。

関連記事