前言:前兩周我帶你們分析了WebGis中關鍵步驟瓦片加載+點擊事件(具體的看前兩篇文章),下面呢,我帶大家來看看Geojson的加載及其點擊事件
Geojson數據解析
GeoJSON是一種對各種地理數據結構進行編碼的格式。GeoJSON對象可以表示幾何、特征或者特征集合。GeoJSON支持下面幾何類型:點、線、面、多點、多線、多面和幾何集合。GeoJSON里的特征包含一個幾何對象和其他屬性,特征集合表示一系列特征。
一個完整的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代碼加載
至于如何加載地圖在第一篇的加載瓦片式地圖已經提過了,看完第一篇的你應該知道我是將地圖map交接給頁面的div中,而map中包含了很多遮罩層,我現在加載GeoJSON就是在最上面的層上在加載url數據。
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上私信我或者在留言板上留言
效果欣賞
1、地圖加載完畢 這里你看到的地圖不是上次的了,這次這個地圖就是GeoJSON里的數據,只不過將數據以圖形化的形式展現在我們的面前,看到地圖右上方的兩個點和一條線了嗎,那都是通過數據動態加載出來的,換句話來說就是,我只需要將GeoJSON里的數據進行修改一下,這個地圖就不一樣了,這很方便我們在后臺修改地圖。還有這個中國的框架也是數據里的,總之一句話你看到的這個地圖里所有元素都是數據里設置的(除了樣式)
2、放大縮小地圖和之前效果一樣,值得注意的是我在js中設置了顯示級別,就是放大縮小的不同級別顯示的數據也是不同的,比如說那條線吧,我設置在6級以上的才能看到,下面我縮小地圖線就不見了,下面是消失了的并不是太小看不見的
3、在放大到一定級別我設置了點的周圍顯示點的名稱!看效果
這里就是加載的效果,下面我們繼續探討。下面就是點擊事件了,點擊事件在上篇文章我是著重講了原理及實現,而在新技術中我們的點擊事件就很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 |
此處參考的w3School
在我的地圖中我就隨便加了幾個試試效果的。
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加載地圖已經講解完畢了,上述只是為了幫助各位梳理思路,并不是項目的完整代碼,如果新入門的沒有看明白,可以在博客下方留言,我會將源碼發送給你。