行政区划浏览 最后更新时间: 2023年08月08日
DistrictExplorer(行政区划浏览) 提供了全国范围内到区县一级的行政区划数据(含边界),同时提供一些辅助功能,比如区划面绘制、事件监听,以及快速判断经纬度所属的子级区划等。
区划数据的组织方式如下图:一个AreaNode代表一份数据,包含父级(ParentFeature)区划和其下辖的多个子级(SubFeature)区划的信息,以父级区划的编码命名。区划信息的内容包括:区划编码(adcode),名称,中心位置(通常为政府所在地),边界信息等。
全国到区县是一个4级的树形结构,而DistrictExplorer却采用了如上所示的两级打包方式进行组织,原因在于边界数据的处理,具体来说:
- 边界需要抽稀至浏览器能够(快速)处理的程度:地理边界具备一定的分形特征,理论上可以无限长(想象一下用十倍,百倍,万倍的显微镜观察陆地边缘),但传输给浏览器的数据大小肯定是有限的(比如100k左右比较合适),绘制的点的数量也是有限的(比如1000个),这就意味着需要有选择性的保留一小部分节点,这就是边界的抽稀。
- 第二,区划的周长不同,抽稀强度也应有所不同:比如,全国的边界周长远远大于北京市朝阳区的边界周长。如果每百米取一个点(仅示意),对北京朝阳区可能刚刚好,但全国的边界数据就会非常大,或者说,此时全国的边界过于精细了;相反,如果采用每万米取一个点,朝阳区的边界可能会缩略到一个点,这样又太简略了。
- 第三,边界抽稀存在“传导”问题:边界是有共享性的,比如北京市延庆区和河北省共享一部分边界,河北省和内蒙古共享一部分边界,内蒙古又和全国共享一部分边界。这么“传导”下来,区到全国的抽稀强度应该是相同的(和第二点存在冲突),否则就会出现共享的边界不能重合的情况(对同样的边界抽取了不同的节点)。
DistrictExplorer做了目的性的取舍,重点针对两级浏览(比如全国范围内显示省级区划,某省范围内显示市级区划等)的场景,优先保证在一千像素高度时,父级“像素可辩”,子级“严丝合缝”。具体做法就是:上下级一起打包成一个AreaNode,独立进行边界抽稀。从最终的数据大小来看,单个AreaNode所用的数据文件大小在15k~150k之间,平均60k左右(gzip后在30k),加总的大小大致相当于区域查询服务提供的边界数据的 1/10。
两级打包也存在一个明显的弊端,即同一个区划会出现在两个AreaNode(一个作为子级,一个作为父级)中,而且边界数据因抽稀强度不同而不同。比如下图,同样是香港特别行政区(区划编码 810000),在代表全国的AreaNode(下图左侧,编码100000)中作为子级区划(SubFeature),在代表香港的AreaNode(下图右侧,编码810000)中作为父级区划(ParentFeature)。左侧以全国为尺度进行抽稀,放大到10级后,相对右侧以香港自身为尺度,明显丢失了边界的曲折细节以及若干外围小岛,显得"直来直去"、“粗枝大叶”。
建议开发者在产品设计时把上述“弊端”作为一个约束考虑进去,随着地图的放大,引导用户切换到低级区划的AreaNode单独查看,这一点类似于文件夹,不是一次性全部浏览,而是一层层展开。AreaNode自身也提供了一个最佳缩放级别(IdealZoom)的信息,供开发者在设计切换场景时参考。
浏览器支持:
现代浏览器和 IE9 及以上
名词释义
如何使用
1、引入UI组件库
2、加载DistrictExplorer(模块名:ui/geo/DistrictExplorer)
//加载DistrictExplorer,loadUI的路径参数为模块名中 'ui/' 之后的部分
AMapUI.loadUI(['geo/DistrictExplorer'], function(DistrictExplorer) {
//启动页面
initPage(DistrictExplorer);
});
function initPage(DistrictExplorer) {
//创建一个实例
var districtExplorer = new DistrictExplorer({
map: map //关联的地图实例
});
var adcode = 100000; //全国的区划编码
districtExplorer.loadAreaNode(adcode, function(error, areaNode) {
if (error) {
console.error(error);
return;
}
//绘制载入的区划节点
renderAreaNode(districtExplorer, areaNode);
});
}
function renderAreaNode(districtExplorer, areaNode) {
//清除已有的绘制内容
districtExplorer.clearFeaturePolygons();
//just some colors
var colors = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00"];
//绘制子级区划
districtExplorer.renderSubFeatures(areaNode, function(feature, i) {
var fillColor = colors[i % colors.length];
var strokeColor = colors[colors.length - 1 - i % colors.length];
return {
cursor: 'default',
bubble: true,
strokeColor: strokeColor, //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线宽
fillColor: fillColor, //填充色
fillOpacity: 0.35, //填充透明度
};
});
//绘制父级区划,仅用黑色描边
districtExplorer.renderParentFeature(areaNode, {
cursor: 'default',
bubble: true,
strokeColor: 'black', //线颜色
fillColor: null,
strokeWeight: 3, //线宽
});
//更新地图视野以适合区划面
map.setFitView(districtExplorer.getAllFeaturePolygons());
}
接口文档
构造参数
方法
事件
注意:需要开启 eventSupport 以及 setAreaNodesForLocating 。
区域节点 - AreaNode
AreaNode实例不能直接创建,需要由上述的 loadAreaNode 或者 loadMultiAreaNodes 方法获取。