OpenLayers 3用户绘制图层转GeoJSON保存后无法显示求助
看起来你遇到的核心问题是投影不匹配,加上服务端不必要的JSON处理导致的图层加载失败,我来帮你一步步解决:
问题根源
投影坐标不兼容:
OpenLayers的Draw交互默认在地图的视图投影(EPSG:3857,墨卡托投影)下工作,你导出的GeoJSON坐标是EPSG:3857格式的大数字,但ol.format.GeoJSON()默认会假设GeoJSON的坐标是EPSG:4326(WGS84经纬度),它会尝试把这些大数字当成经纬度转换到EPSG:3857,结果坐标完全偏离可视区域,导致图层看不到。服务端冗余且危险的JSON处理:
你用eval("(" + oggetto_mappa + ")")再重新JSON.stringify的操作完全多余——客户端已经生成了合法的GeoJSON字符串,eval不仅没必要,还存在代码注入的安全风险,甚至可能破坏原有的JSON结构。
分步解决方案
1. 修正客户端导出逻辑(关键)
在导出GeoJSON时,明确指定投影转换规则,把EPSG:3857的坐标转换成标准的EPSG:4326经纬度:
function addInteractions() { draw = new ol.interaction.Draw({ source: source, type: typeSelect.value }); draw.on("drawend", function(e) { var f = e.feature; features.push(f); // 替换原来的writeFeatures调用,添加投影参数 geoJson = format.writeFeatures(features, { featureProjection: 'EPSG:3857', // 当前地图的投影 dataProjection: 'EPSG:4326' // 导出GeoJSON使用的标准投影 }); console.log(geoJson); document.getElementById('js-textarea').value = geoJson; }); map.addInteraction(draw); snap = new ol.interaction.Snap({source: source}); map.addInteraction(snap); }
修改后导出的GeoJSON坐标会变成类似[9.688053, 45.362760]的经纬度,符合GeoJSON的标准规范。
2. 简化服务端保存代码
直接写入客户端传来的GeoJSON字符串,去掉冗余的eval和重复序列化:
// 直接使用客户端传来的oggetto_mappa字符串写入文件 require("fs").writeFile("./public/data/" + id_perc + ".json", oggetto_mappa, 'utf8', function(f_err) { if(f_err) console.log(f_err); });
3. (可选)如果想保留墨卡托坐标加载
如果你不想转换投影,坚持用EPSG:3857坐标加载,需要在创建GeoJSON格式时明确指定数据投影:
source: new ol.source.Vector({ url: geoDataUrl, format: new ol.format.GeoJSON({ dataProjection: 'EPSG:3857', // 告诉OpenLayers你的GeoJSON用的是墨卡托投影 featureProjection: 'EPSG:3857' // 和地图投影一致 }) })
不过更推荐第一种方法,因为EPSG:4326是GeoJSON的通用标准,兼容性更好。
验证方法
修改后导出的JSON文件里,coordinates应该是经纬度格式的小数,而不是原来的大数字。用这个文件测试你的展示函数,图层应该就能正常显示在地图上了。
内容的提问来源于stack exchange,提问作者Simone Muletti




