我有一个网页,该网页可以从本地数据库中获取一些标记针的位置,还可以从远程GeoJSON源(API)中获取功能的集合。
当前,用户可以使用两个复选框,以允许他们选择要查看的两层中的哪一层。一切正常:
<script>
// Center the map
var map = L.map('map').setView([54.233669, -4.406027], 6);
// Attribution
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=REMOVED', {
attribution: 'Map © <a href="https://www.openstreetmap.org/">OpenStreetMap</a>',
id: 'mapbox.streets'
}).addTo(map);
// Create an empty layergroup for the Locations data
var LayerLocations = L.layerGroup();
// Format the popup markers for the Locations
function forEachFeature(feature, layer) {
// Image
var ImageContent
if (feature.properties.ImageURL) {
ImageContent = "<img src='" + feature.properties.ImageURL + "' width='300' height='200' /><br /><br />"
} else if (feature.properties.YouTubeID) {
ImageContent = "<img src='https://img.youtube.com/vi/" + feature.properties.YouTubeID + "/hqdefault.jpg' width='300' height='200' /><br /><br />"
} else {
ImageContent = ""
}
// Build the popup content
var popupContent = "<h4>" +
feature.properties.Title +
Author +
"</h4>" +
ImageContent +
CommentsContent +
"View and discuss this location.";
layer.bindPopup(popupContent);
}
// Build layer: Locations
fetch("JSONMapPoints.json")
.then(function (response) { return response.json() })
.then(function (data) {
// Create a L.GeoJSON out of the data
var locations = L.geoJson(data, {
onEachFeature: forEachFeature,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {
icon: L.icon({
iconUrl: "images/pins/" + feature.properties.CategoryID + ".png",
iconSize: [32, 37],
iconAnchor: [10, 32],
popupAnchor: [5, -30]
}),
})
}
});
// Add the L.GeoJSON instance to the empty layergroup
map.fitBounds(locations.getBounds());
LayerLocations.addLayer(locations).addTo(map);
});
// Create an empty layergroup for the Guardian UTM data
var LayerGuardianUTM = L.layerGroup();
// Style the Guardian UTM features
function setStyle(feature) {
return {
fillColor: feature.properties.fillColor,
color: feature.properties.strokeColor,
fillOpacity: feature.properties.fillOpacity,
opacity: feature.properties.strokeOpacity
};
}
// Build Layer: Guardian UTM
function getGuardianUTMdata() {
LayerGuardianUTM.clearLayers();
fetch("https://example.com/v2/mapdata/geojson?n=" + map.getBounds().getNorth() + "&e=" + map.getBounds().getEast() + "&s=" + map.getBounds().getSouth() + "&w=" + map.getBounds().getWest(), { headers: { 'Authorization': 'REMOVED', 'X-AA-DeviceId': 'mySite' } })
.then(function (responseGuardianUTM) { return responseGuardianUTM.json() })
.then(function (dataGuardianUTM) {
// Create a L.GeoJSON out of the data
var featuresAA = L.geoJson(dataGuardianUTM, {
style: setStyle,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, { icon: L.icon({ iconUrl: feature.properties.iconUrl }), })
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.name);
},
});
// Add the L.GeoJSON instance to the empty layergroup
LayerGuardianUTM.addLayer(featuresAA).addTo(map);
});
}
// Update the Guardian UTM layer if the map moves
map.on('dragend', function () { getGuardianUTMdata(); });
map.on('zoomend', function () { getGuardianUTMdata(); });
// Layer controls
var layerControl = new L.Control.Layers(null, {
'Locations': LayerLocations,
'Restrictions & Hazards': LayerGuardianUTM
}).addTo(map);
</script>
我希望增加最终用户可用的功能。
我希望通过一个API而不是一个复选框来打开/关闭Restrictions & Hazards
层,而要遍历从API返回的GeoJSON,并根据{{ 1}}。
因此,当用户单击“图层”按钮图标时,他们应该看到一系列复选框,使他们可以选择想要查看的GeoJSON中的哪些功能。
从API返回的GeoJSON是动态的,其内容根据用户位置和缩放级别而变化。
GeoJSON的示例是:
feature.properties.filters.name
基于示例GeoJSON,“图层”按钮应包含以下复选框:
{
"isCompleteData": true,
"excludedData": [],
"countriesInViewport": [],
"nationalFlightRestrictions": [],
"features": [
{
"geometry": {
"coordinates": [
[
-2.6300508975982666,
53.536331176757812
],
[
-2.6293964385986328,
53.533683776855469
],
[
-2.6288816928863525,
53.531524658203125
],
[
-2.6228303909301758,
53.529739379882813
],
[
-2.6218380928039551,
53.528053283691406
],
[
-2.6206841468811035,
53.526073455810547
]
],
"type": "LineString"
},
"id": "A05B59534A594F20583A3B8EB479F211E507F265",
"properties": {
"hazardFactor": "40",
"hazardFactorName": "Warning",
"fillColor": "#ffbb00",
"strokeColor": "#b88702",
"fillOpacity": "0.35",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "power:line",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=power_line.png",
"name": "Power Line",
"category": "groundHazard",
"filters": [
{
"name": "Ground Hazards",
"property": "show",
"active": true
}
],
"display": {
"category": "Ground Hazard",
"detailedCategory": "Power Line",
"title": "Ground Hazard",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=power_line.png",
"title": "Power Hazard",
"text": "The highlighted area is believed to contain power infrastructure. Power infrastructure presents heightened risk of damage to your equipment and critical National infrastructure."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Yellow zones indicate regions where operation of your drone may raise security, privacy or safety concerns."
}
],
"actions": []
}
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
-2.6228303909301758,
53.529739379882813
],
"type": "Point"
},
"id": "6EB24E66D75083A4A135296C12BE004D79629818",
"properties": {
"hazardFactor": "40",
"hazardFactorName": "Warning",
"fillColor": "#ffbb00",
"strokeColor": "#b88702",
"fillOpacity": "0.35",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "power:tower",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=power_tower.png",
"name": "Power Pylon",
"category": "groundHazard",
"filters": [
{
"name": "Ground Hazards",
"property": "show",
"active": true
}
],
"display": {
"category": "Ground Hazard",
"detailedCategory": "Power Pylon",
"title": "Ground Hazard",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=power_tower.png",
"title": "Power Hazard",
"text": "The highlighted area is believed to contain power infrastructure. Power infrastructure presents heightened risk of damage to your equipment and critical National infrastructure."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Yellow zones indicate regions where operation may raise security, privacy or safety concerns."
}
],
"actions": []
}
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
[
[
-2.6234986782073975,
53.533077239990234
],
[
-2.6215133666992187,
53.528900146484375
],
[
-2.6183879375457764,
53.529270172119141
],
[
-2.6178712844848633,
53.529655456542969
]
]
],
"type": "Polygon"
},
"id": "557952B3668AC5DF5C583BE8E8C1840D97B5ABD4",
"properties": {
"hazardFactor": "40",
"hazardFactorName": "Warning",
"fillColor": "#ffbb00",
"strokeColor": "#b88702",
"fillOpacity": "0.35",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "landuse:cemetery",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=landuse_cemetery.png",
"name": "Wigan Borough Cemetery",
"category": "groundHazard",
"filters": [
{
"name": "Ground Hazards",
"property": "show",
"active": true
}
],
"display": {
"category": "Ground Hazard",
"detailedCategory": "Cemetery",
"title": "Wigan Borough Cemetery",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Yellow zones indicate regions where operation of your drone may raise security, privacy or safety concerns."
}
],
"actions": []
}
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
[
[
-3.235,
53.53694
],
[
-3.05278,
53.45944
],
[
-3.20139,
53.38583
],
[
-3.02778,
53.24083
],
[
-2.73028,
53.10722
]
]
],
"type": "Polygon"
},
"id": "616CB45B9DA924146E9A5483843B588B36F0AD31",
"properties": {
"hazardFactor": "60",
"hazardFactorName": "Danger",
"fillColor": "#ffffff",
"strokeColor": "#ffffff",
"fillOpacity": "0.2",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "type:tma",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=class_type_tma.png",
"airac": {
"to": "2019-08-15",
"from": "2019-07-18"
},
"altitudeFloor": {
"datum": "Msl",
"meters": 1066.7999983784639,
"feet": 3499.9999946799994
},
"altitudeCeiling": {
"datum": "Sps",
"meters": 7467.5999886492482,
"feet": 24499.99996276
},
"name": "MANCHESTER TMA 1",
"listOrderHint": "1000",
"category": "airspace",
"designator": "EGCC1",
"airspaceType": "TMA",
"filters": [
{
"name": "Upper Airspace",
"property": "show",
"active": false
},
{
"name": "Type TMA",
"property": "show",
"active": true
}
],
"display": {
"category": "airspace",
"detailedCategory": "Type TMA",
"title": "MANCHESTER TMA 1",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Altitude",
"text": "This piece of airspace is in effect above 1067m / 3500ft MSL"
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Terminal control area",
"text": "Control area normally established at the confluence of ATS routes in the vicinity of one or more major aerodromes."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Regulated Airspace",
"text": "This airspace has a specific classification."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Red zones are regulated high-risk areas."
}
],
"actions": []
}
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
[
[
-3.05278,
53.45944
],
[
-2.06667,
53.575
],
[
-2.83333,
53.53333
],
[
-3.05278,
53.45944
]
]
],
"type": "Polygon"
},
"id": "BC69E04789D9A790DB5B29B0EE2804D42E4FA12A",
"properties": {
"hazardFactor": "60",
"hazardFactorName": "Danger",
"fillColor": "#ffffff",
"strokeColor": "#ffffff",
"fillOpacity": "0.2",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "class:d",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=class_d.png",
"airac": {
"to": "2019-08-15",
"from": "2019-07-18"
},
"altitudeFloor": {
"datum": "Msl",
"meters": 761.99999884176,
"feet": 2499.9999961999997
},
"altitudeCeiling": {
"datum": "Msl",
"meters": 1066.7999983784639,
"feet": 3499.9999946799994
},
"name": "MANCHESTER CTA 1",
"listOrderHint": "600",
"category": "airspace",
"designator": "EGCC1",
"airspaceClass": "D",
"airspaceType": "CTA",
"filters": [
{
"name": "Upper Airspace",
"property": "show",
"active": false
},
{
"name": "Class D",
"property": "show",
"active": true
}
],
"display": {
"category": "airspace",
"detailedCategory": "Class D",
"title": "MANCHESTER CTA 1",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Altitude",
"text": "This piece of airspace is in effect above 762m / 2500ft MSL"
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Regulated Airspace",
"text": "This airspace has a specific classification."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Red zones are regulated high-risk areas."
}
],
"actions": []
}
},
"type": "Feature"
},
{
"geometry": {
"coordinates": [
[
[
-10,
54.56667
],
[
-9,
54.75
],
[
-8.25,
55.33333
]
]
],
"type": "Polygon"
},
"id": "11DD2D3CBA8992F29E49A277FC322D19FCD67066",
"properties": {
"hazardFactor": "60",
"hazardFactorName": "Danger",
"fillColor": "#ffffff",
"strokeColor": "#ffffff",
"fillOpacity": "0.2",
"strokeWidth": "1",
"strokeOpacity": "0.8",
"detailedCategory": "type:cta",
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=class_type_cta.png",
"airac": {
"to": "2019-08-15",
"from": "2019-07-18"
},
"altitudeFloor": {
"datum": "Sps",
"meters": 7467.5999886492482,
"feet": 24499.99996276
},
"altitudeCeiling": {
"datum": "Sps",
"meters": 20116.799969422464,
"feet": 65999.99989968
},
"name": "UPPER AIRSPACE CTA",
"listOrderHint": "1000",
"category": "airspace",
"designator": "EGUP",
"airspaceType": "CTA",
"filters": [
{
"name": "Upper Airspace",
"property": "show",
"active": false
},
{
"name": "Type CTA",
"property": "show",
"active": true
}
],
"display": {
"category": "airspace",
"detailedCategory": "Type CTA",
"title": "UPPER AIRSPACE CTA",
"sections": [
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Altitude",
"text": "This piece of airspace is in effect above FL244.9999996276"
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Control area",
"text": "A controlled airspace extending upwards from a specified limit above the earth."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Regulated Airspace",
"text": "This airspace has a specific classification."
},
{
"iconUrl": "https://aa-ne-prod-public-api.example.com//v1/map/icon?icon=warning.png",
"title": "Summary",
"text": "Red zones are regulated high-risk areas."
}
],
"actions": []
}
},
"type": "Feature"
}
],
"bbox": [
-2.6261,
53.5288,
-2.6201,
53.5308
],
"type": "FeatureCollection"
}
Locations
Ground Hazards
这有可能吗?!
答案 0 :(得分:3)
创建多个L.GeoJSON
实例,并利用其filter
option:
一个
Function
,将用于决定是否包括功能。默认值为包括所有功能:function (geoJsonFeature) { return true; }
注意:动态更改filter选项仅对新添加的数据有效。它不会重新评估已经包含的功能。
例如:
fetch("JSONMapPoints.json")
.then(function (response) { return response.json() })
.then(function (data) {
var locations = L.geoJson(data, {
filter: function(feat) { return feat.properties.filters.name === 'Location'},
/* etc */
});
var hazards = L.geoJson(data, {
filter: function(feat) { return feat.properties.filters.name === 'Hazard'},
/* etc */
});
var airspace = L.geoJson(data, {
filter: function(feat) { return feat.properties.filters.name === 'Air Space'},
/* etc */
});
});
对于那些不同的L.GeoJSON
实例,将它们添加到图层控件中仅是调用addOverlay()
的问题,例如
layersControl.addOverlay(locations, "Locations");
layersControl.addOverlay(hazards, "Hazards);
layersControl.addOverlay(airspace, "Air Space");
请注意scope。 JS的一个新手错误是假设,该变量将在需要的范围内神奇地存在。在这种情况下,我将确保在创建GeoJSON图层时已实例化图层控件,并将其添加到所述图层控件中。
一种更复杂的方法是自动检测类别或过滤器,遍历GeoJSON结构以获取它们,例如:
fetch("JSONMapPoints.json")
.then(function (response) { return response.json() })
.then(function (data) {
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set
var categories = new Set();
for (var i in data) {
var feature = data[i];
categories.add(feature.properties.filters.name);
}
然后遍历类别以编程方式创建L.GeoJSON
实例,并注意适当的闭包:
categories.forEach(function(category) {
var layer = L.geoJSON(data, {
filter: function(f){ f.properties.filters.name === category }
/* etc */ });
layersControl.addOverlay(layer, category);
});
// And we're done here.
});
这对于需要三个过滤器的数据集来说有点过分设计,但是当数量更大时,效果很好。