1.3. 使用GeoJSON和Leaflet

GeoJSON非常简单、轻量级、直截了当。它正在成为许多地理信息系统技术和服务的一种非常流行的数据格式。Leaflet非常擅长处理GeoJSON。在本例中,您将学习如何在GeoJSON对象中创建地图矢量并与之交互。

View this example

1.3.1. GeoJSON简介

根据GeoJSON规范(RFC 7946):GeoJSON是一种用于编码各种地理数据结构的格式。GeoJSON对象可以表示几何图形、要素或要素集。GeoJSON支持以下几何图形类型:点、直线、多点、多线、多边形和几何图形。GeoJSON中的要素包含几何对象和其他特性,要素集表示一系列要素。

Leaflet支持上述所有GeoJSON类型,但功能和功能集执行得最好,因为它们允许使用一组属性来描述功能,甚至可以使用这些属性来设计Leaflet矢量。以下是一个简单的GeoJSON功能的示例:

var geojsonFeature = {
    "type": "Feature",
    "properties": {
        "name": "Coors Field",
        "amenity": "Baseball Stadium",
        "popupContent": "This is where the Rockies play!"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.99404, 39.75621]
    }
};

1.3.2. GeoJSON层

GeoJSON对象通过GeoJSON层添加到地图。要创建它并将其添加到地图,可使用以下代码:

L.geoJSON(geojsonFeature).addTo(map);

GeoJSON对象也可以作为有效的GeoJSON对象的数组传递。

var myLines = [{
    "type": "LineString",
    "coordinates": [[-100, 40], [-105, 45], [-110, 55]]
}, {
    "type": "LineString",
    "coordinates": [[-105, 40], [-110, 45], [-115, 55]]
}];

或者,可以创建一个空的GeoJSON层并将其赋给一个变量,以便稍后添加更多要素。

var myLayer = L.geoJSON().addTo(map);
myLayer.addData(geojsonFeature);

1.3.3. style 选项

style 选项可用于以两种不同的方式设置样式。首先,我们可以通过一个简单的对象以相同的方式设置所有路径(折线和多边形)的样式:

var myLines = [{
    "type": "LineString",
    "coordinates": [[-100, 40], [-105, 45], [-110, 55]]
}, {
    "type": "LineString",
    "coordinates": [[-105, 40], [-110, 45], [-115, 55]]
}];

var myStyle = {
    "color": "#ff7800",
    "weight": 5,
    "opacity": 0.65
};

L.geoJSON(myLines, {
    style: myStyle
}).addTo(map);

或者,可以使用函数来设置其各种属性的样式。在下面的示例中,检查“party”属性并相应地设置多边形样式:

var states = [{
"type": "Feature",
"properties": {"party": "Republican"},
"geometry": {
    "type": "Polygon",
    "coordinates": [[
        [-104.05, 48.99],
        [-97.22,  48.98],
        [-96.58,  45.94],
        [-104.03, 45.94],
        [-104.05, 48.99]
    ]]
}
}, {
    "type": "Feature",
    "properties": {"party": "Democrat"},
    "geometry": {
        "type": "Polygon",
        "coordinates": [[
            [-109.05, 41.00],
            [-102.06, 40.99],
            [-102.03, 36.99],
            [-109.04, 36.99],
            [-109.05, 41.00]
        ]]
    }
}];

L.geoJSON(states, {
    style: function(feature) {
        switch (feature.properties.party) {
            case 'Republican': return {color: "#ff0000"};
            case 'Democrat':   return {color: "#0000ff"};
        }
    }
}).addTo(map);

点图层( pointToLayer )

点的处理方式与多段线和多边形不同。默认情况下,为GeoJSON点绘制简单标记。创建GeoJSON涂层时,可以通过在GeoJSON选项对象中传递一个函数来更改此设置 pointToLayer 。此函数传递 LatLng 并返回 ILayer 的一个实例,在本例中该实例可能是 MarkerCircleMarker

还可以使用 pointToLayer 选项创建一个循环标记:

var geojsonMarkerOptions = {
    radius: 8,
    fillColor: "#ff7800",
    color: "#000",
    weight: 1,
    opacity: 1,
    fillOpacity: 0.8
};

L.geoJSON(someGeojsonFeature, {
    pointToLayer: function (feature, latlng) {
        return L.circleMarker(latlng, geojsonMarkerOptions);
    }
}).addTo(map);

我们也可以在本例中设置属性的 style ,如果在pointToLayer函数内创建一个圆形矢量层,则Leaflet足够智能,可以将样式应用于GeoJSON点( pointToLayer )。

onEachFeature

onEachFeature 选项是在将每个要素添加到GeoJSON层之前调用的要素。此选项通常用于在单击要素时附加弹出窗口。

function onEachFeature(feature, layer) {
    // does this feature have a property named popupContent?
    if (feature.properties && feature.properties.popupContent) {
        layer.bindPopup(feature.properties.popupContent);
    }
}

var geojsonFeature = {
    "type": "Feature",
    "properties": {
        "name": "Coors Field",
        "amenity": "Baseball Stadium",
        "popupContent": "This is where the Rockies play!"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.99404, 39.75621]
    }
};

L.geoJSON(geojsonFeature, {
    onEachFeature: onEachFeature
}).addTo(map);

过滤器( filter )

此过滤器选项可用于控制GeoJSON功能的可见性。为此,我们通过一个函数设置过滤器选项。此函数由GeoJSON层中的每个元素调用,在传递要素和层后,可以使用此属性中的值通过返回True或来控制可见性False。

在下面的例子中,“Busch field”将不会显示在地图上。

var someFeatures = [{
"type": "Feature",
"properties": {
    "name": "Coors Field",
    "show_on_map": true
},
"geometry": {
    "type": "Point",
    "coordinates": [-104.99404, 39.75621]
}
}, {
    "type": "Feature",
    "properties": {
        "name": "Busch Field",
        "show_on_map": false
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.98404, 39.74621]
    }
}];

L.geoJSON(someFeatures, {
    filter: function(feature, layer) {
        return feature.properties.show_on_map;
    }
}).addTo(map);