/** * 在 Mapbox 中实现点选目标中心点并自动生成面积 1.5 倍裁切框。 * @param {mapboxgl.Map} map - Mapbox map 对象。 * @param {string} container - 用于显示裁切框的 DOM 元素的 ID。 * @param {number} cropFactor - 指定裁切框面积为目标面积的多少倍,默认为 1.5。 */function generateCropBox(map, container, cropFactor = 1.5) { let centerPointCoords = null; let newMap = null; let cropBoxLayer = null; // 添加点击事件,获取目标中心点 map.on("click", function(event) { // 如果已经有对应的裁切框和地图,则先移除再重新生成 if (newMap && newMap.getContainer().parentNode.id === container) { newMap.remove(); } if (cropBoxLayer) { cropBoxLayer.remove(); cropBoxLayer = null; } var features = map.queryRenderedFeatures(event.point); centerPointCoords = features[0].geometry.coordinates; var bounds = new mapboxgl.LngLatBounds(); bounds.extend(centerPointCoords); var area = turf.area(turf.circle(centerPointCoords, 1, {units: "kilometers"})); var targetArea = area * cropFactor; var targetRadius = Math.sqrt(targetArea / Math.PI); var targetBounds = turf.bbox(turf.circle(centerPointCoords, targetRadius, {steps: 128, units: "kilometers"})); bounds.extend([targetBounds[0], targetBounds[1]]); bounds.extend([targetBounds[2], targetBounds[3]]); // 创建新地图,显示裁切框 newMap = new mapboxgl.Map({ container: container, style: map.getStyle(), bounds: bounds.toArray(), maxBounds: bounds.toArray(), zoom: 12 }); // 添加 GeoJSON 图层,显示目标区域和裁切框 var geojson = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Point", coordinates: centerPointCoords }, properties: { name: "Target" } }, { type: "Feature", geometry: { type: "Polygon", coordinates: [ [ [targetBounds[0], targetBounds[1]], [targetBounds[2], targetBounds[1]], [targetBounds[2], targetBounds[3]], [targetBounds[0], targetBounds[3]], [targetBounds[0], targetBounds[1]] ] ] }, properties: { name: "Crop box" } } ] }; newMap.on("load", function() { newMap.addSource("source", { type: "geojson", data: geojson }); newMap.addLayer({ id: "point", type: "circle", source: "source", paint: { "circle-radius": 10, "circle-color": "blue", "circle-stroke-width": 2, "circle-stroke-color": "white" }, filter: ["==", "$type", "Point"] }); cropBoxLayer = newMap.addLayer({ id: "polygon", type: "line", source: "source", layout: { "line-join": "round", "line-cap": "round" }, paint: { "line-color": "#f00", "line-width": 2, "line-opacity": 0.7 }, filter: ["==", "$type", "Polygon"] }); }); });}