提交 0dc567bf 编写于 作者: 牛老师讲GIS's avatar 牛老师讲GIS

上传新文件

上级 d3cabac8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
html, body, .sf-map {
margin: 0;
overflow: hidden;
height: 100%;
}
.cluster-count {
font-size: 14px;
text-shadow: 0 0 2px #fff;
font-weight: bold;
}
</style>
</head>
<body>
<div id="map" class="sf-map">
</div>
<script src="https://lbs.sf-express.com/api/map?v=2.0&ak=664e42802f604c35b8afa2de864c55cb"></script>
<script src="lib/proj4.min.js"></script>
<script>
const map = SFMap.map('map', {
renderer: L.canvas(),
center: [22.161316, 113.567138],
zoom: 4,
})
class Geojson {
constructor(features = [], metaData = {}) {
this.type = 'FeatureCollection'
this.metadata = metaData
this.features = features
}
}
class Geometry {
constructor(type, coordinates) {
this.type = type
this.coordinates = coordinates
}
}
class Feature {
constructor(geomType, properties, coordinates) {
this.type = 'Feature'
this.properties = properties
this.geometry = new Geometry(geomType, coordinates)
}
}
class GridCluster {
constructor(map, data, size = 64, showPoint = true) {
const that = this
this.map = map
this.data = data.map(d => {
d.coords = that.toWeb([d.lon, d.lat])
return d
})
this.size = size
this.val = 20037508.34
this.showPoint = showPoint
this.polygonLayer = null
this.polygonLabel = null
this.pointLayer = null
this.map.on('moveend', () => {
that.polygonLayer.remove()
that.polygonLabel.remove()
that.pointLayer.remove()
that.addCluster()
})
that.addCluster()
}
toLonLat(coords) {
const {x, y} = proj4.transform(proj4.Proj("EPSG:3857"), proj4.Proj("EPSG:4326"), coords)
return [x, y]
}
toWeb(lonlat) {
const {x, y} = proj4.transform(proj4.Proj("EPSG:4326"), proj4.Proj("EPSG:3857"), lonlat)
return [x, y]
}
addCluster() {
const that = this
const z = Math.ceil(that.map.getZoom())
const res = (that.val * 2 / Math.pow(2, z)) / 256 * that.size
let [_x1, _y1, _x2, _y2] = that.map.getBounds().toBBoxString().split(',').map(Number)
const [x1, y1] = that.toWeb([_x1, _y1])
const [x2, y2] = that.toWeb([_x2, _y2])
const count = Math.ceil(that.val * 2 / res)
let features = []
const data = that.data.filter(({coords}) => {
const [x, y] = coords
return x >= x1 && x <= x2 && y >= y1 && y <= y2
})
for(let i = 0; i < count; i++) {
let xmin = i * res - that.val
let xmax = (i+1) * res - that.val
for(let j = 0; j < count; j++) {
let ymax = that.val - j * res
let ymin = that.val - (j+1) * res
const isInExtent = xmin >= x1 && xmin <= x2 && ymin >= y1 && ymin <= y2
|| xmax >= x1 && xmax <= x2 && ymin >= y1 && ymin <= y2
|| xmin >= x1 && xmin <= x2 && ymax >= y1 && ymax <= y2
|| xmax >= x1 && xmax <= x2 && ymax >= y1 && ymax <= y2
if(isInExtent) {
const dataFilter = [...data].filter(({coords}) => {
const [x, y] = coords
return x >= xmin && x <= xmax && y >= ymin && y <= ymax
})
const count = dataFilter.length
if(count > 1) {
const [_xmin, _ymin] = that.toLonLat([xmin, ymin])
const [_xmax, _ymax] = that.toLonLat([xmax, ymax])
const coords = [[[_xmin, _ymin], [_xmax, _ymin], [_xmax, _ymax], [_xmin, _ymax], [_xmin, _ymin]]]
features.push(new Feature('Polygon', {count, extent: [_xmin, _ymin, _xmax, _ymax]}, coords))
}
}
}
}
that.polygonLayer = L.geoJSON(new Geojson(features), {
style: (feature) => {
const count = feature.properties.count
let color = `68, 149, 247`
if(count > 20) {
color = '165,0,179'
} else if(count <= 20 && count > 15) {
color = '255,10,10'
} else if(count <= 15 &&count > 10) {
color = '255,138,5'
} else if(count <= 10 &&count > 5) {
color = '247,176,76'
}
color = `rgb(${color})`
return {
color: color,
weight: 1,
opacity: 1,
fillColor: color,
fillOpacity: 0.5
}
}
}).addTo(map);
that.polygonLabel = L.layerGroup().addTo(map);
features.forEach(feature => {
const {count, extent} = feature.properties
const [xmin, ymin, xmax, ymax] = extent
const [x, y] = [(xmin + xmax) / 2, (ymin + ymax) / 2]
const myIcon = L.divIcon({
html: count,
className: 'cluster-count'
});
L.marker([y, x], { icon: myIcon }).addTo(that.polygonLabel);
})
if(that.showPoint) {
const features = data.map(d => {
return new Feature('Point', d, [d.lon, d.lat])
})
that.pointLayer = L.geoJSON(new Geojson(features), {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, {
radius: 2,
fillColor: "#f00",
color: "#f00",
weight: 1,
opacity: 1,
fillOpacity: 0.6
});
}
}).addTo(map);
}
}
}
fetch('data1/flights.json').then(res => res.json()).then(res => {
let {airports} = res
airports = airports.map(([name, city, country, lon, lat]) => {
return {name, city, country, lon, lat}
}).filter(({lon, lat}) => {
return Boolean(lon) && Boolean(lat)
})
new GridCluster(map, airports)
})
</script>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册