這是我參與更文挑戰的第9天,活動詳情查看: 更文挑戰json
本文正在參加「Java主題月 - Java 開發實戰」,詳情查看 活動連接數組
GeoJSON是一種對各類地理數據結構進行編碼的格式。瀏覽器
前言:前兩週我帶大家分析了WebGis中關鍵步驟瓦片加載+點擊事件(具體的看前兩篇文章),下面呢,我帶你們來看看Geojson的加載及其點擊事件服務器
GeoJSON是一種對各類地理數據結構進行編碼的格式。GeoJSON對象能夠表示幾何、特徵或者特徵集合。GeoJSON支持下面幾何類型:點、線、面、多點、多線、多面和幾何集合。GeoJSON裏的特徵包含一個幾何對象和其餘屬性,特徵集合表示一系列特徵。markdown
一個完整的GeoJSON數據結構老是一個(JSON術語裏的)對象。在GeoJSON裏,對象由名/值對--也稱做成員的集合組成。對每一個成員來講,名字老是字符串。成員的值要麼是字符串、數字、對象、數組,要麼是下面文本常量中的一個:"true","false"和"null"。數組是由值是上面所說的元素組成。數據結構
GeoJSON集合特徵:框架
{"type":"FeatureCollection",
"features":[
{"type":"Feature",
"id":"001",
"properties":{"name":"新華001"},
"geometry":{"type": "Point", "coordinates":[121.9850,42.6737]}},
{"type":"Feature",
"id":"002",
"properties":{"name":"新華002"},
"geometry":{"type": "Point", "coordinates":[121.8345,42.4898]}},
{"type":"Feature",
"id":"003",
"properties":{"name":"峯山1"},
"geometry":{"type": "LineString", "coordinates":[[121.9850,42.6737],[121.8345,42.4898]]}},
{"type":"Feature",
"id":"004",
"properties":{"name":"新華1001"},
"geometry":{"type": "Point", "coordinates":[128.9850,42.6737]}},
{"type":"Feature",
"id":"005",
"properties":{"name":"新華1002"},
"geometry":{"type": "Point", "coordinates":[125.8345,42.4898]}},
{"type":"Feature",
"id":"006",
"properties":{"name":"峯山2"},
"geometry":{"type": "LineString", "coordinates":[[121.9850,42.6737],[125.8345,42.4898]]}}]}
複製代碼
openlayers3代碼加載oop
至於如何加載地圖在第一篇的加載瓦片式地圖已經提過了,看完第一篇的你應該知道我是將地圖map交接給頁面的div中,而map中包含了不少遮罩層,我如今加載GeoJSON就是在最上面的層上在加載url數據。post
var vector = new ol.layer.Vector( {
source : new ol.source.Vector( {
// url:
// 'http://openlayers.org/en/v3.17.1/examples/data/geojson/countries.geojson',
url : './source/china.json',
format : new ol.format.GeoJSON()
}),
style : selectStyleFunction
});
複製代碼
我這是引用本地準備好的數據(能夠從服務器上得到,從服務器上只須要將url地址改寫成服務地址),加載url完成後並不會在map中顯示出來,咱們還須要指定數據的顯示樣式,這裏和以前瓦片是加載不一樣,樣式很重要我調節了很久才調通的,這裏我將封裝在方法裏。編碼
方法的具體實現:
var style;
if(feature.getGeometry().getType()=="Point"){
style = [new ol.style.Style({
image : new ol.style.Circle( {
fill : new ol.style.Fill( {
color : 'rgba(255,255,0,0.4)'
}),
radius : 2,
stroke : new ol.style.Stroke( {
color : 'black',
width : 1
})
}),
text : new ol.style.Text( {
fill : textFill,
stroke : textStroke,
text : view.getZoom()>5?(feature.getId()>2?feature.get("name"):""):""
})
})];
}else if(feature.getGeometry().getType()=="LineString"){
if(view.getZoom()<3){
return ;
}
style = [new ol.style.Style( {
stroke : new ol.style.Stroke( {
color : '#CD950C',
width : 2
}),
text : new ol.style.Text( {
fill : textFill,
stroke : textStroke,
text : view.getZoom()>6?feature.get("name"):""
})
})];
}else if(feature.getGeometry().getType()=="Polygon"){
style = [new ol.style.Style( {
stroke : new ol.style.Stroke( {
color : '#FFE4B5',
width : 3
}),
text : new ol.style.Text( {
fill : textFill,
stroke : textStroke,
text : feature.get("name")
})
})];
}else if(feature.getGeometry().getType()=="MultiLineString"){
style = [new ol.style.Style( {
stroke : new ol.style.Stroke( {
color : 'black',
width : 3
})
})];
}
return style;
複製代碼
申明 裏面有些參數沒有進行申明,由於定義了全局變量,由於在以前的js中改的,因此並沒貼出全部代碼。這裏須要完整代碼的請CSDN上私信我或者在留言板上留言
效果欣賞
一、地圖加載完畢 這裏你看到的地圖不是上次的了,此次這個地圖就是GeoJSON裏的數據,只不過將數據以圖形化的形式展示在咱們的面前,看到地圖右上方的兩個點和一條線了嗎,那都是經過數據動態加載出來的,換句話來講就是,我只須要將GeoJSON裏的數據進行修改一下,這個地圖就不同了,這很方便咱們在後臺修改地圖。還有這個中國的框架也是數據裏的,總之一句話你看到的這個地圖裏全部元素都是數據裏設置的(除了樣式)
二、放大縮小地圖和以前效果同樣,值得注意的是我在js中設置了顯示級別,就是放大縮小的不一樣級別顯示的數據也是不一樣的,好比說那條線吧,我設置在6級以上的才能看到,下面我縮小地圖線就不見了,下面是消失了的並非過小看不見的
三、在放大到必定級別我設置了點的周圍顯示點的名稱!看效果
這裏就是加載的效果,下面咱們繼續探討。下面就是點擊事件了,點擊事件在上篇文章我是着重講了原理及實現,而在新技術中咱們的點擊事件就很Easy了
咱們要在map中綁定事件,也就是註冊事件
map.on('singleclick', mapClick);
複製代碼
function mapClick(e) {
var pixel = map.getEventPixel(e.originalEvent);
var featureInfo = map.forEachFeatureAtPixel(pixel,
function(feature, layer) {
return {
feature : feature,
layer : layer
};
});
var coordinate = e.coordinate;
var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(coordinate,
'EPSG:3857', 'EPSG:4326'));
if (featureInfo !== undefined && featureInfo !== null
&& featureInfo.layer !== null) {
if (featureInfo.feature.get("geometry").B.length == 2) {
// alert(view.getZoom());
alert(hdms + "\n這裏屬於" + featureInfo.feature.get("name") + "點");
} else if (featureInfo.feature.get("geometry").B.length == 4) {
alert(hdms + "\n這裏屬於" + featureInfo.feature.get("name") + "線");
alert("兩端信息" + featureInfo.feature.get("geometry").B);
} else {
// alert(hdms+"\n這裏屬於"+featureInfo.feature.get("name")+"省");//顯示點擊區域的
}
console.log('打印選擇要素');
console.log(featureInfo.feature);
console.log('打印選擇要素所屬Layer');
console.log(featureInfo.layer);
} else {
alert(hdms + "\n這裏不屬於中國或者這裏是大海");// 顯示點擊區域的
}
}
複製代碼
在這裏我須要講解一下:
這裏的featureInfo是咱們在方法裏拼接的(feature+layer)組成的,在if條件判斷裏咱們featureInfo.feature.get("geometry").B.length == 2是判斷feature裏數字點的個數,你們想想若是是點是否是有兩個數字點,若是是線就是兩個點也就是四個數字點,若是是區域的話那就是至少是超過4的偶數了,這樣咱們就能夠區別出點線和區域了,這也就是說咱們在這裏就實現了以前很難解決的點線問題了,區域問題咱們就很少加討論了。
var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(coordinate,'EPSG:3857', 'EPSG:4326'));
複製代碼
這個是將座標進行轉換的,這個很少說
定位
在以前咱們的定位就是以某個點中心顯示並加上圖標那就是所謂的定位,那麼在咱們的新技術中定位是否是有所改變呢?讓咱們來一探究竟。
若是你認爲既然是新技術了就必定要有突破,那麼個人回答可能會讓你很失望,新技術裏仍然是用上述的思想來實現定位的,但多多少少仍是有不一樣的。
| 新舊對比 | openlayers2 | openlayers3 |
|:-------------- |:-------------|:-----|
| 點擊 | 獲取經緯度查詢 | 點線類別區分 |
| 定位 | map中心顯示 | view中心顯示 |
複製代碼
由上圖的表格咱們能夠看出咱們的定位仍是有所區別的,在新技術中我麼能採用的是view中心顯示法,什麼叫view中心顯示法呢,就是經過view來調用設置中心的方法。
view.setCenter(ol.proj.fromLonLat( [
Number(document.getElementById('jd').value),
Number(document.getElementById('wd').value) ]));
複製代碼
其餘經常使用的事件介紹
事件句柄
HTML 4.0 的新特性之一是有能力使 HTML 事件觸發瀏覽器中的動做(action),好比當用戶點擊某個 HTML 元素時啓動一段 JavaScript。下面是一個屬性列表,這些屬性可插入 HTML 標籤來定義事件動做。
具體事件
屬性 | 當如下狀況發生時,出現此事件 | FF | N | IE |
---|---|---|---|---|
onabort | 圖像加載被中斷 | 1 | 3 | 4 |
onblur | 元素失去焦點 | 1 | 2 | 3 |
onchange | 用戶改變域的內容 | 1 | 2 | 3 |
onclick | 鼠標點擊某個對象 | 1 | 2 | 3 |
ondblclick | 鼠標雙擊某個對象 | 1 | 4 | 4 |
onerror | 當加載文檔或圖像時發生某個錯誤 | 1 | 3 | 4 |
onfocus | 元素得到焦點 | 1 | 2 | 3 |
onkeydown | 某個鍵盤的鍵被按下 | 1 | 4 | 3 |
onkeypress | 某個鍵盤的鍵被按下或按住 | 1 | 4 | 3 |
在個人地圖中我就隨便加了幾個試試效果的。
var select = null; // ref to currently selected interaction
// select interaction working on "singleclick"
var selectSingleClick = new ol.interaction.Select();
// select interaction working on "click"
var selectClick = new ol.interaction.Select( {
condition : ol.events.condition.click
});
// select interaction working on "pointermove"
var selectPointerMove = new ol.interaction.Select( {
condition : ol.events.condition.pointerMove
});
var selectAltClick = new ol.interaction.Select( {
condition : function(mapBrowserEvent) {
return ol.events.condition.click(mapBrowserEvent)
&& ol.events.condition.altKeyOnly(mapBrowserEvent);
}
});
var selectElement = document.getElementById('type');
var changeInteraction = function() {
if (select !== null) {
map.removeInteraction(select);
}
var value = selectElement.value;
if (value == 'singleclick') {
select = selectSingleClick;
} else if (value == 'click') {
select = selectClick;
} else if (value == 'pointermove') {
select = selectPointerMove;
} else if (value == 'altclick') {
select = selectAltClick;
} else {
select = null;
}
if (select !== null) {
map.addInteraction(select);
select.on('select', function(e) {
document.getElementById('status').innerHTML = ' '
+ e.target.getFeatures().getLength()
+ ' selected features (last operation selected '
+ e.selected.length + ' and deselected '
+ e.deselected.length + ' features)';
});
}
};
複製代碼
到這裏整個GeoJSON加載地圖已經講解完畢了,上述只是爲了幫助各位梳理思路,並非項目的完整代碼,若是新入門的沒有看明白,能夠在博客下方留言,我會將源碼發送給你。