Vector Layer †
- Raster vs Vector
Raster Layer | サーバ側で作られた地図画像を表示する |
Vector Layer | 端点の情報を元に、クライアントサイド(Javascript)で図形を作成して表示する |
- データ形式
- 図形
- Point
- Multi Point
- Line String
- Multi Line String
- Polygon
- Multi Polygon (飛び地の有るポリゴン)
GeoJSON 形式のデータを Vector Layer に描画する †
- USGS から、2010年〜2015年 のマグニチュード 6 以上の地震の位置(Point)を GeoJSON 形式でダウンロード
http://earthquake.usgs.gov/earthquakes/search/ ⇒ js/earthquake.geojson
- MapQuest? の衛星写真 (Raster) の上に、Vector Layer を置いて、そこに地震発生箇所を描画する
- マウスクリックで GeoJSON の付帯情報を表示する。
「クリック位置の緯度,経度 ⇒ クリック位置のピクセル座標 ⇒ そのピクセルにある図形の付帯情報」の順で GeoJSON の付帯情報を取得する
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css"/>
<link rel="stylesheet" href="css/sample.css" type="text/css"/>
<style>
body {
padding : 0;
margin : 0;
}
</style>
<title>OpenLayers 3 example 10 Earthquake</title>
</head>
<body>
<div id="map" class="map"></div>
<div id="overlay" style="background-color:white; border: 1px solid black; padding: 5px 10px;"></div>
<script src="js/ol-debug.js"></script>
<script type="text/javascript">
var rasterLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: 'js/earthquake.geojson'
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var overlay = new ol.Overlay({
element: document.getElementById('overlay'),
positioning: 'bottom-center'
});
var map = new ol.Map({
target: 'map',
layers: [rasterLayer, vectorLayer],
view: new ol.View({
center: ol.proj.transform([135, 35], 'EPSG:4326', 'EPSG:3857'),
zoom: 3
})
});
map.on('click', function(e) {
var coordinate = e.coordinate;
var pixel = map.getPixelFromCoordinate(coordinate);
var label = '';
map.forEachFeatureAtPixel(pixel, function(feature){
// the attribute data of GeoJSON of USGS earthquake data.
var date = new Date(feature.get('time'));
label += feature.get('title') + ' @ ' + date.getFullYear() + '<br/>';
});
if (label.length > 0) {
var element = overlay.getElement();
element.innerHTML = label;
overlay.setPosition(coordinate);
map.addOverlay(overlay);
}
});
</script>
</body>
</html>
REST API から今描画に必要なデータを取得する †
- 固定データの場合には ol.source.Vector に format と url を指定すればよかった
- 必要箇所を動的に取得するには ol.source.Vector に loader と strategy を指定する
- loader : function(extent, resolution, projection)
- 引数 extent に、現在表示している地図に必要な領域が EPSG:3857 で格納されている
たとえば
[-60112525.02836773, -2665308.711046496, 60112525.02836773, 13106401.957203632]
これをGETパラメータに乗っけて GeoJSON を返す REST API を呼び出す
http://...../cgi-bin/getMap?bbox=-60112525.02836773, -2665308.711046496, 60112525.02836773, 13106401.957203632&callback=
とか
- strategy
- ol.source.Vector に format と url を指定した場合、内部的には ol.featureloader.xhr が使われる
- 下のサンプルは Natural Earth から、精度 110m の地図をダウンロードしてきて、GeoJSON 形式に変換して衛星写真の上に配置。マウスクリックで国名が表示される
cf. HTML D3.js Globe
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css"/>
<link rel="stylesheet" href="css/sample.css" type="text/css"/>
<style>
body {
padding : 0;
margin : 0;
}
</style>
<title>OpenLayers 3 example 11 Countries</title>
</head>
<body>
<div id="map" class="map"></div>
<div id="overlay" style="background-color:white; border: 1px solid black; padding: 5px 10px;"></div>
<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/ol-debug.js"></script>
<script type="text/javascript">
var rasterLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var vectorSource = new ol.source.Vector({
loader: function(extent, resolution, projection) {
console.log(extent);
var url = 'js/countries.geojson';
$.getJSON(url, function(json) {
var features = new ol.format.GeoJSON().readFeatures(json,{
featureProjection: projection
});
vectorSource.addFeatures(features);
});
},
strategy: ol.loadingstrategy.all
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var overlay = new ol.Overlay({
element: document.getElementById('overlay'),
positioning: 'bottom-center'
});
var map = new ol.Map({
target: 'map',
layers: [rasterLayer, vectorLayer],
view: new ol.View({
center: ol.proj.transform([135, 35], 'EPSG:4326', 'EPSG:3857'),
zoom: 3
})
});
map.on('click', function(e) {
var coordinate = e.coordinate;
var pixel = map.getPixelFromCoordinate(coordinate);
map.forEachFeatureAtPixel(pixel, function(feature){
// the attribute data of GeoJSON of Natural Earth data.
var label = feature.get('formal_en');
var element = overlay.getElement();
element.innerHTML = label;
overlay.setPosition(coordinate);
map.addOverlay(overlay);
});
});
</script>
</body>
</html>
いろいろな図形を地図に描画する †
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css"/>
<link rel="stylesheet" href="css/sample.css" type="text/css"/>
<style>
body {
padding : 0;
margin : 0;
}
</style>
<title>OpenLayers 3 example 12 Polygon</title>
</head>
<body>
<div id="map" class="map"></div>
<script src="js/ol-debug.js"></script>
<script type="text/javascript">
var featureArray = new ol.Collection();
featureArray.push(createCircleFeature({lng:-60, lat:10}, 10));
featureArray.push(createLineFeature({lng:-30, lat:10}, 10));
featureArray.push(createPointFeature({lng:0, lat:10}, 10));
featureArray.push(createRectFeature({lng:30, lat:10}, 10));
var vectorSource = new ol.source.Vector({
features: featureArray
});
var vectorLayer = new ol.layer.Vector({
source : vectorSource
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectorLayer
],
view: new ol.View({
center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'),
zoom: 2
})
});
/**
* Create Circle Feature.
* @param center provide center {lng,lat}
* @param size referential width
* @return feature
*/
function createCircleFeature(center, size) {
var geom = new ol.geom.Circle([center.lng, center.lat], size);
geom.transform('EPSG:4326', 'EPSG:3857');
return new ol.Feature(geom);
}
/**
* Create Line Feature.
* @param center provide center {lng,lat}
* @param size referential width
* @return feature
*/
function createLineFeature(center, size) {
var shape = [
[center.lng + size, center.lat - size], // east-south
[center.lng - size, center.lat + size], // west-north
[center.lng + size, center.lat + size], // east-north
];
var geom = new ol.geom.LineString(shape);
geom.transform('EPSG:4326', 'EPSG:3857');
return new ol.Feature(geom);
}
/**
* Create Point Feature.
* @param center provide center {lng,lat}
* @param size referential width
* @return feature
*/
function createPointFeature(center, size) {
var geom = new ol.geom.Point([center.lng, center.lat]);
geom.transform('EPSG:4326', 'EPSG:3857');
return new ol.Feature(geom);
}
/**
* Create Rectangle Feature.
* @param center provide center {lng,lat}
* @param size referential width
* @return feature
*/
function createRectFeature(center, size) {
var shape = [
[center.lng + size, center.lat - size], // east-south
[center.lng + size, center.lat + size], // east-north
[center.lng - size, center.lat + size], // west-north
[center.lng - size, center.lat - size], // west-south
[center.lng + size, center.lat - size], // east-south (start)
];
var geom = new ol.geom.Polygon([shape]);
geom.transform('EPSG:4326', 'EPSG:3857');
return new ol.Feature(geom);
}
</script>
</body>
</html>
ol.source.GeoJSON は、3.5 で廃止 †
GIS