jQuery mobileのスタイルをあてたコントロールが表示されない

スクロールするDIVにjQuery Mobileのスタイルをあてたcheckboxを表示

最初は正しく表示されている

スクロールするとなぜか一番下が表示されない

再度一番上を確認すると表示されない

ちなみにjQuery Mobileのスタイルをあてないcheckboxは問題ない

再描画の問題なのか?DOMのキャッシュの問題なのか?

DIVのスタイルから以下を外すと表示されない問題は解決

-webkit-overflow-scrolling: touch

Leafletにユーザーコントロールを追加

ユーザーコントロール:ourCustomControl を作成してmapに登録。
ちなみにユーザーコントロールのクリックイベントが発生するとMAPにもイベントが伝搬してしまうので、
クリックイベントではe.stopPropagation();を読んでMAPにイベントだ伝搬することを停止。

var ourCustomControl = L.Control.extend({
	options: {
		position: 'topleft' 
		//control position - allowed: 'topleft', 'topright', 'bottomleft', 'bottomright'
	},
	onAdd: function (map) {
		var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
		container.style.backgroundColor = 'white';
		container.style.width = '30px';
		container.style.height = '30px';
		container.onclick = function(e){
			e.stopPropagation();
		  	console.log('buttonClicked');
			//drawControl.options.draw = true;
			new L.Draw.Marker(map, drawControl.options.marker).enable();
		}
		return container;
	},
});

map.addControl(new ourCustomControl());

参考Creating custom control button in leaflet

Leaflet Draw

LeafLet DrawはLeaflet上でFeatureを登録編集するプラグイン

GITHUBのURL

https://github.com/Leaflet/Leaflet.draw

基本的な使い方
githubよりSRC以下をダウンロードしてリンク

	<script src="../lib/leafret.draw/src/Leaflet.draw.js"></script>
    <script src="../lib/leafret.draw/src/Leaflet.Draw.Event.js"></script>

    <script src="../lib/leafret.draw/src/Toolbar.js"></script>
    <script src="../lib/leafret.draw/src/Tooltip.js"></script>

    <script src="../lib/leafret.draw/src/ext/GeometryUtil.js"></script>
    <script src="../lib/leafret.draw/src/ext/LatLngUtil.js"></script>
    <script src="../lib/leafret.draw/src/ext/LineUtil.Intersect.js"></script>
    <script src="../lib/leafret.draw/src/ext/Polygon.Intersect.js"></script>
    <script src="../lib/leafret.draw/src/ext/Polyline.Intersect.js"></script>
    <script src="../lib/leafret.draw/src/ext/TouchEvents.js"></script>
    <script src="../lib/leafret.draw/src/draw/DrawToolbar.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Feature.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.SimpleShape.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Polyline.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Marker.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Circle.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.CircleMarker.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Polygon.js"></script>
    <script src="../lib/leafret.draw/src/draw/handler/Draw.Rectangle.js"></script>
    <script src="../lib/leafret.draw/src/edit/EditToolbar.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/EditToolbar.Edit.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/EditToolbar.Delete.js"></script>
    <script src="../lib/leafret.draw/src/Control.Draw.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.Poly.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.SimpleShape.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.Rectangle.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.Marker.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.CircleMarker.js"></script>
    <script src="../lib/leafret.draw/src/edit/handler/Edit.Circle.js"></script>

    <link rel="stylesheet" href="../lib/leafret.draw/src/leaflet.draw.css"/>

以下のコードでツールバーが表示され、編集等が可能となる

var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);

var drawControl = new L.Control.Draw({
     edit: {
         featureGroup: drawnItems
     }
 });
 map.addControl(drawControl);

map.on(L.Draw.Event.CREATED, function (event) {
	var layer = event.layer;
	drawnItems.addLayer(layer);
});

登録用ツールバーを消去

var drawControl = new L.Control.Draw({
	 draw : false,
     edit: {
		featureGroup: drawnItems
     },
 });

編集削除ツールバーも消去

var drawControl = new L.Control.Draw({
	 draw : false,
     edit: {
		featureGroup: drawnItems,
		edit: false,
		remove: false
     },
 });

消去を再表示はできない?

一旦、コントロールそのものを削除して再登録だな。

削除のコード

 map.removeControl(drawControl);

iPhoneを回転するとzoomControlが隠れる

Leafletモバイルのサンプルページに従ってページを作成。
Leaflet on Mobile
iPhone SE iOSのバージョンは10.3.2
最初はzoomControlも正しい位置に表示されているが、回転するとzoomControlがアドレスバーに隠れてしまう。

HTMLとCSS

body {
    padding: 0;
    margin: 0;
}
html, body, #map {
    height: 100vh;
    width: 100vw;
}

対応は回転のイベントで以下の処理を行う

$(window).bind("orientationchange",function(){
    setTimeout(function(){
        $('html,body').animate({scrollTop: 0}, 500, 'swing');
        map.invalidateSize()
}, 400);
})

GeoServerが動かない→Tomcatが動かない

GeoServerが動作しないためTomcatのサービスを確認すると起動していない。
サービスを起動しようとすると以下のエラーが表示される。

イベントログには以下が出力されている「Apache Tomcat 7.0 Tomcat7 サービスは、次のサービス固有エラーで終了しました: ファンクションが間違っています。」

どうやらJavaがバージョンアップされてTomcatが参照しているJREの場所を更新する必要があるようだ。

環境変数:JRE_HOME

JRE_HOME=C:\Program Files\Java\jre1.8.0_111\bin

C:\Program Files\Apache Software Foundation\Tomcat 7.0\bin\Tomcat7w.exeを起動して
jvm.dllのパスを確認

C:\Program Files\Java\jre1.8.0_111\bin\server\jvm.dll

JREのディレクトリ確認

最初にインストールした「jre1.8.0_111」から「jre1.8.0_131」にバージョンアップされている。

Tomcat7w.exeの値と環境変数をいかに修正

C:\Program Files\Java\jre1.8.0_131\bin\server\jvm.dll

C:\Program Files\Java\jre1.8.0_131\bin

今更ながらの小地域

e-Statでダウンロード可能な最小の地域である小地域とは基本的には町丁目または大字字である。

西池袋3丁目の場合は「西池袋」が「町」、「3丁目」が「丁目」である。

大字と字は見つけたら記載の予定

カテゴリー: GIS

今更ながらのe-statから小地域データのダウンロード

統計局のe-Statから小地域(町丁目、大字、字)のポリゴンと国勢調査の結果などがダウンロードできる。
久しぶりにサイトに来るとダウンロードの方法が分からなくなるので記載。

s-Statを開き、「地図や図表で見る」→「地図で見る統計(統計GIS)」を選択。

「データダウンロード」を選択

国勢調査(小地域)を選択し、統計表より対象項目を選択

対象都道府県、市区町村を選択して「検索」ボタンを実行し、ダウンロードサイトが表示される。

google map上にwmsレイヤを表示

OpenLayers向けに構築したシステムをgooglemapに置き換えたときにできるだけ使えるリソースは再利用したい。
今回はgeoserverで提供しているWMSレイヤ(タイルとシングルタイル)を表示する方法を調査。

タイル(256×256)の使い方

var mapOptions = {
	center: new google.maps.LatLng(y, x),
	zoom: scale,
	mapTypeId: google.maps.MapTypeId.ROADMAP,
	scaleControl: true,
	scaleControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER }
}
var map_canvas = new google.maps.Map(document.getElementById(id_map), mapOptions);

var SLPLayer = new google.maps.ImageMapType({
    getTileUrl: 
		function (coord, zoom) {
	        var proj = map_canvas.getProjection();
	        var zfactor = Math.pow(2, zoom);                      
	        var ul = new google.maps.Point(coord.x * 256.0 / zfactor , (coord.y + 1) * 256.0 / zfactor );
	        var lr = new google.maps.Point((coord.x + 1) * 256.0 / zfactor , (coord.y) * 256.0 / zfactor );
	        var ulw = proj.fromPointToLatLng(ul);
	        var lrw = proj.fromPointToLatLng(lr); 	                               
	        var bbox = ulw.lng() + "," + ulw.lat() + "," + lrw.lng() + "," + lrw.lat();
	        var url = "http://maps4/geoserver/省略/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap";
	        url += "&TRANSPARENT=true"; //WMS operation
	        url += "&LAYERS=mesh3"; //WMS layers
	        url += "&FORMAT=image/png" ; //WMS format
	        url += "&TILED=false" ;
	        url += "&viewparams=on";
	        url += "&CRC=EPSG:4326";     //set WGS84 
	        url += "&BBOX=" + bbox;      // set bounding box
	        url += "&WIDTH=256";         //tile size in google
	        url += "&HEIGHT=256";
	        return url;                 // return URL for the tile
    	},
    tileSize: new google.maps.Size(256, 256),
    isPng: true
});
map_canvas.overlayMapTypes.push(SLPLayer);

シングルタイルの使い方
google.maps.ImageMapTypeは引数で指定した「tileSize」のサイズに従って世界中をタイルに分割する
※下図参照
getTileUrlの引数coordにはタイルのXYのインデックスが渡ってくる。

よってmap_canvas.overlayMapTypesをシングルタイルに使おうとしてもどうしてもぴったりにはならない。
tileSizeを大きくしてもどうしても最大4つのタイルを使用してしますが、とりあえずその方法について記載。

var SLPLayer = new google.maps.ImageMapType({
    getTileUrl: 
		function (coord, zoom) {

	        var zfactor = Math.pow(2, zoom);                      
	        var proj = map_canvas.getProjection();
	        var ul = new google.maps.Point(coord.x * 1536.0 / zfactor , (coord.y + 1) * 1024.0 / zfactor );
	        var lr = new google.maps.Point((coord.x + 1) * 1536.0 / zfactor , (coord.y) * 1024.0 / zfactor );

			//var ne = map_canvas.getBounds().getNorthEast();
			//var sw = map_canvas.getBounds().getSouthWest();
	        //var bbox = sw.lng() + "," + sw.lat() + "," + ne.lng() + "," + ne.lat();

	        var ulw = proj.fromPointToLatLng(ul);
	        var lrw = proj.fromPointToLatLng(lr); 	                               
	        var bbox = ulw.lng() + "," + ulw.lat() + "," + lrw.lng() + "," + lrw.lat();


			//base WMS URL
			var url = "http://maps4/geoserver/省略/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap";
			url += "&TRANSPARENT=true"; //WMS operation
			url += "&LAYERS=shop"; //WMS layers
			url += "&FORMAT=image/png" ; //WMS format
			url += "&CRC=EPSG:4326";     //set WGS84 
			url += "&BBOX=" + bbox;      // set bounding box
			url += "&WIDTH=1536";         //tile size in google
			url += "&HEIGHT=1024";
			return url;                 // return URL for the tile
    },
    tileSize: new google.maps.Size(1536, 1024),
    isPng: true
});
map_canvas.overlayMapTypes.push(SLPLayer);

もちろんふたつのレイヤを重ねることは可能

参考サイト

SeedCollectorをiOS9に対応(2)

HTTP通信の許可設定

iPad上で通信時に以下のエラーが発生

App Transport Security has blocked a cleartext HTTP (http://) resource load 
since it is insecure. 

iOS9よりHTTPで通信するにはATSを無効にするか、例外対象のドメインを設定する必要がある。

(1)例外対象のドメインを設定

info.plistのキー「App Transport Security Settings」に「Exception Domains」以下を追加

※設定したがなぜか正しく機能しない

(2)ATSを無効にする

info.plistのキー「App Transport Security Settings」に「Allow Arbitrary Loads」を追加しYESに設定

こちらは期待通りに機能した

iOS9でHTTP通信ができない時の解決法を参考

カメラ利用の設定

カメラ利用時にエラーが発生し、以下のログを出力

カメラを使用するアプリはinfo.plistに記載

これでカメラ使用時に確認メッセージが表示される。

カメラの変更

iOS7対応時にカメラをUImagePickerControllerに変更しViewControllerとして使用していたが、正しく画像が保存されていなかった。

よってpopoverで表示するように変更。

変更前

//----------------------------------------------------------------------
// 写真撮影View表示
//----------------------------------------------------------------------
-(void)showInputPhoto:(Query*)query AnchorButton:(UIButton*)button Value:(NSString*)value{
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]==YES){
        showing_modal = YES;
        if(ip2){
            [ip2 release];
        }
        ip2 = [[vInputPhoto2 alloc]initWithAppConf:appconf Query:query Value:value];
        ip2.imagepicker = imagepicker;
        [ip2 setDelegate:self];
        //[self showPopOver: ip2.imagepicker AnchorButton:button];
        [CmnLib showViewController:self Child:ip2.imagepicker];
    }
}

変更後

//----------------------------------------------------------------------
// 写真撮影View表示
//----------------------------------------------------------------------
-(void)showInputPhoto:(Query*)query AnchorButton:(UIButton*)button Value:(NSString*)value{
    if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]==YES){
        showing_modal = YES;
        if(ip2){
            [ip2 release];
        }
        ip2 = [[vInputPhoto2 alloc]initWithAppConf:appconf Query:query Value:value];
        ip2.imagepicker = imagepicker;
        [ip2 setDelegate:self];
        [self showPopOver: ip2.imagepicker AnchorButton:button];
        //[CmnLib showViewController:self Child:ip2.imagepicker];
    }
}

以上を「201707appstore更新SeedCollector」の候補として検証を開始

カテゴリー: iOS