如何通过Mapshaper CLI为不同要素设置可变简化百分比?
如何在Mapshaper中为不同地理要素设置差异化的简化百分比?
问题背景
我需要处理NaturalEarthData的10m级别「Admin 0 – Details > map units」数据,目标是将25MB的原文件压缩至1MB以内。110m级别同类数据大小符合要求,但缺少必要要素,因此无法使用。
尝试全局简化命令:
mapshaper ne_10m_admin_0_map_units.geo.json -simplify 1% keep-shapes -o simplified.geo.json
后,博奈尔岛的简化效果极差;将简化百分比提升至12%时,博奈尔岛的效果达标,但其他区域的多边形细节保留过多,导致文件体积超出限制。
我希望为不同区域设置差异化的简化百分比(比如小区域用12%,其他区域用5%)。根据Mapshaper的文档,simplify命令的variable参数允许percentage=选项接收JS表达式,且-each命令中可通过this对象获取要素信息。于是编写了如下JS脚本:
function percentage() { console.log( this ) return 0.01 } exports.percentage = percentage
执行命令:
mapshaper ne_10m_admin_0_map_units.geo.json -require js_expression.js alias=_ -simplify variable percentage='_.percentage()' weighted keep-shapes -o simplified.geo.json
发现console.log(this)输出的是模块对象{ percentage: [Function: percentage] },而非预期的要素对象。请问如何实现按区域设置不同的简化百分比?是否有其他替代方法?
解决方案
一、修复JS脚本的要素上下文问题
通过-require导入的模块函数,默认执行上下文是模块本身,而非当前要素对象。要获取要素信息,需将this(当前要素)作为参数传入模块函数:
- 修改JS脚本,接收要素参数:
function getPercentage(feature) { // 根据要素属性判断,示例:匹配博奈尔岛名称 return feature.NAME === "Bonaire" ? 0.12 : 0.05; // 也可根据面积判断:return feature.AREA < 0.1 ? 0.12 : 0.05; } exports.getPercentage = getPercentage;
- 执行命令时传递要素对象:
mapshaper ne_10m_admin_0_map_units.geo.json -require js_expression.js alias=_ -simplify variable percentage='_.getPercentage(this)' weighted keep-shapes -o simplified.geo.json
二、直接使用内联JS表达式(无需外部脚本)
如果逻辑简单,可直接在命令行中编写表达式,此时this直接指向当前要素对象:
mapshaper ne_10m_admin_0_map_units.geo.json -simplify variable percentage='this.NAME === "Bonaire" ? 0.12 : 0.05' weighted keep-shapes -o simplified.geo.json
三、先标记要素简化属性,再批量简化
对于更复杂的判断逻辑,可先用-each命令为每个要素添加自定义简化百分比字段,再基于该字段执行简化:
# 第一步:添加simplify_pct字段,按面积阈值区分 mapshaper ne_10m_admin_0_map_units.geo.json -each 'this.simplify_pct = this.AREA < 0.1 ? 0.12 : 0.05' \ # 第二步:基于自定义字段执行差异化简化 -simplify variable percentage='this.simplify_pct' weighted keep-shapes -o simplified.geo.json
四、分层处理+合并(替代方案)
如果需要对特定区域做极致控制,可拆分要素分别处理后合并:
- 提取并简化小区域:
mapshaper ne_10m_admin_0_map_units.geo.json -filter 'NAME === "Bonaire"' -simplify 12% keep-shapes -o small_areas.json
- 简化其余区域:
mapshaper ne_10m_admin_0_map_units.geo.json -filter 'NAME !== "Bonaire"' -simplify 5% keep-shapes -o other_areas.json
- 合并两个文件:
mapshaper small_areas.json other_areas.json -merge-files -o final_simplified.json
内容的提问来源于stack exchange,提问作者Eric G
相关产品推荐
相关产品推荐

