假设您有一个 GeoJSON 特征集合,其中包含在 Leaflet 地图中显示的相邻彩色多边形;在本案中,里斯本市的教区
运行代码片段以查看地图
fetch('https://geoapi.pt/municipio/lisboa/freguesias?json=1').then(r => r.json()).then(data => {
const geojsons = data.geojsons
var map = L.map('map')
const bbox = geojsons.municipio.bbox
const corner1 = L.latLng(bbox[1], bbox[0])
const corner2 = L.latLng(bbox[3], bbox[2])
const bounds = L.latLngBounds(corner1, corner2)
map.fitBounds(bounds)
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map)
// feature collection
const parishesGeoJsonFeatureCollection = {
type: 'FeatureCollection',
features: geojsons.freguesias
}
// need this for color pallete
const numberOfParishes = parishesGeoJsonFeatureCollection.features.length
parishesGeoJsonFeatureCollection.features.forEach((parish, index) => {
parish.properties.index = index
})
L.geoJson(parishesGeoJsonFeatureCollection, {
style
}).addTo(map)
function style (feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.index, numberOfParishes)
}
}
})
// get random color
function getColor (index, size) {
const colors = {
3: ['#8dd3c7', '#ffffb3', '#bebada'],
4: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072'],
5: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3'],
6: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462'],
7: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69'],
8: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5'],
9: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9'],
10: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd'],
11: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5'],
12: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f']
}
if (size < 3) {
return colors[3][index]
} else if (size <= 12) {
return colors[size][index]
} else {
return colors[12][index % 12]
}
}
#map { height: 220px; }
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
crossorigin=""></script>
<div id="map"></div>
您将如何应用四色定理或任何合适的算法来避免相邻的多边形具有相同的颜色?
感谢来自other stack exchange site的@TomazicM,我可以实现它。请相应地给他投票,而不是我,我只是在这里发帖让刚到这里的用户知道,因为 SO 允许插入代码片段,因此你可以看到它在现场工作。
它利用了另一个名为TopoJSON
的库const colors = ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f']
function style (feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7,
fillColor: colors[feature.properties.colorIndex]
}
}
fetch('https://geoapi.pt/municipio/lisboa/freguesias?json=1').then(r => r.json()).then(data => {
const geojsons = data.geojsons
var map = L.map('map')
const bbox = geojsons.municipio.bbox
const corner1 = L.latLng(bbox[1], bbox[0])
const corner2 = L.latLng(bbox[3], bbox[2])
const bounds = L.latLngBounds(corner1, corner2)
map.fitBounds(bounds)
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map)
// feature collection
const parishesGeoJsonFeatureCollection = {
type: 'FeatureCollection',
features: geojsons.freguesias
}
var topoJSON = topojson.topology([parishesGeoJsonFeatureCollection], 1e4);
var neighbors = topojson.neighbors(topoJSON.objects[0].geometries);
var featureColors = [];
parishesGeoJsonFeatureCollection.features.forEach((parish, index) => {
for (var i = 0; i < colors.length; i++) {
var found = false;
for (var j = 0; j < neighbors[index].length; j++) {
if (featureColors[neighbors[index][j]] == i) {
found = true;
break;
}
}
if (!found) break;
}
featureColors[index] = i;
parish.properties.colorIndex = i;
});
L.geoJson(parishesGeoJsonFeatureCollection, {
style
}).addTo(map)
})
#map { height: 220px; }
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI="
crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
crossorigin=""></script>
<script src="https://unpkg.com/topojson@3"></script>
<div id="map"></div>