Skip to content

Instantly share code, notes, and snippets.

@abruzzi
Last active August 29, 2015 13:59
Show Gist options
  • Save abruzzi/10711036 to your computer and use it in GitHub Desktop.
Save abruzzi/10711036 to your computer and use it in GitHub Desktop.
How to styling the openlayer vector layers (generated by geojson)
app.controller('EventController',
['$scope', '$compile', '$timeout', function($scope, $compile, $timeout) {
var map = new OpenLayers.Map("map");
var osm = new OpenLayers.Layer.OSM();
var style = new OpenLayers.Style();
var ruleLow = new OpenLayers.Rule({
filter: new OpenLayers.Filter.Function({
evaluate: function(properties) {
return properties.mag < 3.0;
}
}),
symbolizer: {pointRadius: 3, fillColor: "green",
fillOpacity: 0.5, strokeColor: "black"}
});
var ruleHigh = new OpenLayers.Rule({
filter: new OpenLayers.Filter.Function({
evaluate: function(properties) {
return properties.mag >= 3.0;
}
}),
symbolizer: {pointRadius: 5, fillColor: "red",
fillOpacity: 0.7, strokeColor: "black"}
});
style.addRules([ruleLow, ruleHigh]);
var geo = new OpenLayers.Layer.Vector("EarthQuake", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: '/all_day.geojson',
format: new OpenLayers.Format.GeoJSON({ignoreExtraDims: true})
})
});
geo.styleMap = new OpenLayers.StyleMap(style);
map.addLayers([osm, geo]);
if(!map.getCenter()) {
map.zoomToMaxExtent();
}
}]);

OpenLayers

使用OpenLayers可以很容易的搭建基于Web的GIS系统,OpenLayers支持不同的数据源(符合WMS协议的服务器,Google Maps API, Bing Virtual Earth,KML以及GeoJSON等等)。通过将不同的数据源的数据整合,我们可以开发出丰富而用户友好的GIS系统。

OpenLayers可以轻松的处理GeoJSON数据,并将其生成矢量层,我们可以将这个层叠加在其他数据源(比如OSM)提供的地图上,以得到一个完整的小应用。

GeoJSON

美国地理信息调查局是一个科学组织,他公开了很多地球上的灾难信息,比如对地震的统计,并提供编程接口。它公开的地震统计信息,包含全世界各地报告过的地震,以及全美所有检测到的地震,并以多种周期(小时,天,周,月等),多种格式(GeoJSON,KML,Atom等),以便应用程序的开发者只用这些数据。

实现

基本代码

一个最简单的OpenLayers应用,只需要7行代码:

$(function() {
    var map = new OpenLayers.Map("map");
    var osm = new OpenLayers.Layer.OSM();

    map.addLayers([osm]);

    if(!map.getCenter()) {
        map.zoomToMaxExtent();
    }
});

这段代码在id为map的HTML元素创建了一个地图,这个地图上有一个叫OSM的层(即OpenStreetMap,一个开源,开放的地图平台),并将地图缩小到边界范围(以获得最大的视野)

生成矢量层

通过GeoJSON生成矢量图非常容易:

var geo = new OpenLayers.Layer.Vector("EarthQuake", {
    strategies: [new OpenLayers.Strategy.Fixed()],
    protocol: new OpenLayers.Protocol.HTTP({
        url: '/all_day.geojson',
        format: new OpenLayers.Format.GeoJSON({ignoreExtraDims: true})
    })
});

注意此处的all_day.geojson是从USGS网站上下载的,过去一天中世界各地的所有地震统计。

上边的代码创建了一个名称为EarthQuake的矢量层,strategies中的Fixed策略表示仅请求一次资源,然后缓存在前端,不再请求。protocol表明数据来源为all_day.geojson,格式为OpenLayers.Format.GeoJSON。由于USGS返回的地理信息除了经纬度还包含深度,而OpenLayers默认只处理经纬度的,因此需要此处的ignoreExtraDims来忽略那个额外的深度信息。

[image]

定制样式

虽然我们已经加上了新的层,也可以看到很多表示地震的点信息,但是并不能看出哪些地震是严重的,比如里氏3级以下的地震,几乎没有危害,可以标注成一种颜色;而更高震级的可以标记成另外一种颜色。

OpenLayers可以很容易的做到这个定制化:

    var style = new OpenLayers.Style();

    var ruleLow = new OpenLayers.Rule({
      filter: new OpenLayers.Filter.Function({
            evaluate: function(properties) {
                return properties.mag < 3.0;
            }
        }),
      symbolizer: {pointRadius: 3, fillColor: "green",
                   fillOpacity: 0.5, strokeColor: "black"}
    });

    var ruleHigh = new OpenLayers.Rule({
      filter: new OpenLayers.Filter.Function({
            evaluate: function(properties) {
                return properties.mag >= 3.0;
            }
        }),
        symbolizer: {pointRadius: 5, fillColor: "red",
                   fillOpacity: 0.7, strokeColor: "black"}
    });

    style.addRules([ruleLow, ruleHigh]);

    geo.styleMap = new OpenLayers.StyleMap(style);

首先创建一个Style对象,为Style添加两条规则Rule,然后将Style对象包装成StyleMap并赋值给表示地震的矢量层earthquake

对于规则ruleLow,我们定义了,当一个feature的属性值mag(震级)小于三的时候后,使用绿色的,半径为3px的小圆圈来表示。而ruleHigh则定义了当震级大于等于三的时候,用红色,半径为5px的圆圈来表示。

加上事件处理

虽然我们已经可以直观的根据震级不同而看到不同颜色的点,但是整个应用仍然没有多少意义:它不具备于用户的交互能力。我们需要添加上事件处理,当用户点击地图上的一个圆点的时候,应该看到一个更详细的窗口。

var selectControl = new OpenLayers.Control.SelectFeature(geo, {
    onSelect: onFeatureSelect,
    onUnselect: onFeatureUnselect 
});

map.addControl(selectControl);
selectControl.activate();

function onFeatureSelect(feature) {
    var html = "<span>"+feature.attributes.title+"</span>";

    var popup = new OpenLayers.Popup.FramedCloud("popup",
            feature.geometry.getBounds().getCenterLonLat(),
            null,
            html,
            null,
            true
        );

    popup.panMapIfOutOfView = true;
    popup.autoSize = true;

    feature.popup = popup;

    map.addPopup(popup);
}

function onFeatureUnselect(feature) {
    map.removePopup(feature.popup);
    feature.popup.destroy();
    feature.popup = null;
}

我们在地图上添加了一个SelectFeature元素,并注册了回调函数:当矢量层中的矢量被选中之后,函数onFeatureSelect将被执行,我们可以在这个函数中添加对弹出窗口的控制。当onFeatureSelect执行时,OpenLayers会将当前的Feature传递进来,我们可以动态的取得震级,标题,链接等信息,并展现给最终用户。

[image]

var selectControl = new OpenLayers.Control.SelectFeature(geo, {
onSelect: onFeatureSelect,
onUnselect: onFeatureUnselect
});
map.addControl(selectControl);
selectControl.activate();
function onFeatureSelect(feature) {
var html = "<span>"+feature.attributes.title+"</span>";
var popup = new OpenLayers.Popup.FramedCloud("popup",
feature.geometry.getBounds().getCenterLonLat(),
null,
html,
null,
true
);
popup.panMapIfOutOfView = true;
popup.autoSize = true;
feature.popup = popup;
map.addPopup(popup);
}
function onFeatureUnselect(feature) {
map.removePopup(feature.popup);
feature.popup.destroy();
feature.popup = null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment