前台调用
iD编辑器通过瓦片区域向后台请求数据,瓦片大小位置固定。页面根据当前显示范围请求数据,iD根据请求范围计算出需要请求的瓦片坐标,异步请求所有的瓦片,将返回数据加载到页面。代码在/modules/services/osm.js里。获取页面数据方法如下:
// Load data (entities) from the API in tiles
// GET /api/0.6/map?bbox=
loadTiles: function(projection, callback) {
if (_off) return;
// determine the needed tiles to cover the view
// 此处计算出当前页面需要请求的瓦片数组
var tiles = tiler.zoomExtent([_tileZoom, _tileZoom]).getTiles(projection);
// abort inflight requests that are no longer needed
// 此处判断如果此瓦片正在请求中不再重复请求
var hadRequests = hasInflightRequests(_tileCache);
abortUnwantedRequests(_tileCache, tiles);
if (hadRequests && !hasInflightRequests(_tileCache)) {
dispatch.call('loaded'); // stop the spinner
}
// issue new requests..
// 调用loadTile方法请求数据
tiles.forEach(function(tile) {
this.loadTile(tile, callback);
}, this);
}
获取单个瓦片数据方法如下:
// Load a single data tile
// 获取单个瓦片数据
// GET /api/0.6/map?bbox=
loadTile: function(tile, callback) {
if (_off) return;
if (_tileCache.loaded[tile.id] || _tileCache.inflight[tile.id]) return;
// 请求状态加入缓存,避免重复请求
if (!hasInflightRequests(_tileCache)) {
dispatch.call('loading'); // start the spinner
}
// 后台接口路径
var path = '/map?bbox=';
var options = { skipSeen: true };
// 调用loadFromAPI方法执行后台接口调用
_tileCache.inflight[tile.id] = this.loadFromAPI(
// tile.extent.toParam()是瓦片坐标,格式为[最小经度,最小纬度,最大经度,最大纬度]
// 例如:bbox=113.80737304687499,36.16448788632064,113.8128662109375,36.16892253622743
path + tile.extent.toParam(),
tileCallback,
options
);
// 回调函数
function tileCallback(err, parsed) {
delete _tileCache.inflight[tile.id];
if (!err) {
delete _tileCache.toLoad[tile.id];
_tileCache.loaded[tile.id] = true;
var bbox = tile.extent.bbox();
bbox.id = tile.id;
_tileCache.rtree.insert(bbox);
}
if (callback) {
callback(err, Object.assign({ data: parsed }, tile));
}
if (!hasInflightRequests(_tileCache)) {
dispatch.call('loaded'); // stop the spinner
}
}
}
后台返回数据结构
iD使用的数据为XML格式,例如:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<emg>
<bounds minlat="36.16448788632064" minlon="113.80737304687499" maxlat="36.16892253622743" maxlon="113.8128662109375"/>
<node id="20000029511229" visible="true" version="0" changeset="0" lat="36.1660274714116" lon="113.812499024776">
<tag k="junctiontype" v="1"/>
</node>
<node id="20000029605604" visible="true" version="0" changeset="0" lat="36.165942736831" lon="113.812521179214"/>
<node id="20000166841255" visible="true" version="0" changeset="0" lat="36.1658888660772" lon="113.812532432277"/>
<node id="20000166841256" visible="true" version="0" changeset="0" lat="36.164399080032" lon="113.812843633737"/>
<node id="20000029511577" visible="true" version="0" changeset="0" lat="36.164341" lon="113.812855766076">
<tag k="junctiontype" v="1"/>
</node>
<way id="20000005107585" visible="true" version="1" ver="2019-02-19 13:33:49.143072" changeset="0">
<nd ref="20000029511229"/>
<nd ref="20000029605604"/>
<nd ref="20000166841255"/>
<nd ref="20000166841256"/>
<nd ref="20000029511577"/>
<tag k="emapgo" v="base"/>
<tag k="editable" v="yes"/>
<tag k="namec" v="228省道"/>
</way>
</emg>
node为道路的节点,包含id、经度、纬度和版本等信息,如果节点有属性还包含tag信息。
way为道路,包含id和版本等信息。道路属性为tag信息,道路节点为nd信息,道路按此节点顺序连接。