D3.js 无法缩放或平移图块
D3.js can't zoom or pan tiles
我已经尝试了大约 10 天来使用 D3.js 创建显示矢量数据 (geojson) 的地图和我可以缩放和平移的栅格图块,但无法让它正常工作。我可以缩放和平移矢量数据,但不能缩放平移图块。
我注意到,当我调用 tile(transform)
时,尽管在转换中有我认为有意义的数字(例如 {"k": 1, " x”:-35,“y”:-37})。我在搞什么鬼?我假设问题出在下面的代码片段中的某个地方,尽管我还有完整的代码。
const tile = d3.tile()
.extent([[0, 0], [width, height]])
let zoom = d3.zoom()
.on('zoom', () => zoomed(d3.event.transform))
svg.call(zoom)
function zoomed(transform) {
const tiles = tile(transform);
lines.attr('transform', transform.toString())
images = images.data(tiles, d => d)
.join('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr('y', ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
下面是数据和完整的脚本。
{
"type": "FeatureCollection",
"name": "lines",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": 3}, "geometry": { "type": "LineString", "coordinates": [ [ -74.201304101157845, 40.033790926216739 ], [ -74.201226425025339, 40.033761910802717 ], [ -74.201164135201353, 40.033738641825124 ] ] } },
{ "type": "Feature", "properties": { "id": 4}, "geometry": { "type": "LineString", "coordinates": [ [ -74.200521185229846, 40.034804885753857 ], [ -74.200535458528648, 40.034780636493231 ], [ -74.200698022608137, 40.034504451003734 ], [ -74.200932444446437, 40.034106179618831 ], [ -74.201017665586349, 40.033961391736824 ] ] } },
{ "type": "Feature", "properties": { "id": 5}, "geometry": { "type": "LineString", "coordinates": [ [ -74.243246789888346, 40.038535382572938 ], [ -74.243221882547942, 40.038496558418132 ], [ -74.243182498790546, 40.038435169141529 ], [ -74.243137176965064, 40.038364523771932 ], [ -74.243057495263045, 40.038240319569326 ], [ -74.242984178076739, 40.038126035633333 ], [ -74.242983803896664, 40.038125452375041 ], [ -74.242970932683164, 40.03810547276553 ], [ -74.242927580863451, 40.038038178902433 ] ] } }
]
}
let width = 900,
height = 500,
initialScale = 1 << 17,
initialCenter = [-74.20465,39.98783]
let svg = d3.select('body')
.append('svg')
.attr('height', height)
.attr('width', width)
let map = svg.append('g')
let images = map.append('g')
.attr('pointer-events', 'none')
.selectAll('image');
let glines = map.append('g')
let lines = glines.append('g')
let projection = d3.geoMercator()
.scale(initialScale)
.center(initialCenter)
.translate([width / 2, height / 2])
let path = d3.geoPath(projection)
const tile = d3.tile()
.extent([[0, 0], [width, height]])
let zoom = d3.zoom()
.on('zoom', () => zoomed(d3.event.transform))
svg.call(zoom)
function zoomed(transform) {
const tiles = tile(transform);
lines.attr('transform', transform.toString())
images = images.data(tiles, d => d)
.join('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr('y', ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
function drawMap(data) {
let tiles = tile
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]))();
lines.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('class', 'line')
.attr('d', path)
images = images.data(tiles, d => d)
.enter()
.append('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', d => (d[0] + tiles.translate[0]) * tiles.scale)
.attr('y', d => (d[1] + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
d3.json('test.geojson').then(drawMap)
我找到了一种更简单的方法,可以使用 D3 + Leaflet 在底图上放置线条。请参阅 https://observablehq.com/@sfu-iat355/intro-to-leaflet-d3-interactivity。创造奇迹。
我已经尝试了大约 10 天来使用 D3.js 创建显示矢量数据 (geojson) 的地图和我可以缩放和平移的栅格图块,但无法让它正常工作。我可以缩放和平移矢量数据,但不能缩放平移图块。
我注意到,当我调用 tile(transform)
时,尽管在转换中有我认为有意义的数字(例如 {"k": 1, " x”:-35,“y”:-37})。我在搞什么鬼?我假设问题出在下面的代码片段中的某个地方,尽管我还有完整的代码。
const tile = d3.tile()
.extent([[0, 0], [width, height]])
let zoom = d3.zoom()
.on('zoom', () => zoomed(d3.event.transform))
svg.call(zoom)
function zoomed(transform) {
const tiles = tile(transform);
lines.attr('transform', transform.toString())
images = images.data(tiles, d => d)
.join('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr('y', ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
下面是数据和完整的脚本。
{
"type": "FeatureCollection",
"name": "lines",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": 3}, "geometry": { "type": "LineString", "coordinates": [ [ -74.201304101157845, 40.033790926216739 ], [ -74.201226425025339, 40.033761910802717 ], [ -74.201164135201353, 40.033738641825124 ] ] } },
{ "type": "Feature", "properties": { "id": 4}, "geometry": { "type": "LineString", "coordinates": [ [ -74.200521185229846, 40.034804885753857 ], [ -74.200535458528648, 40.034780636493231 ], [ -74.200698022608137, 40.034504451003734 ], [ -74.200932444446437, 40.034106179618831 ], [ -74.201017665586349, 40.033961391736824 ] ] } },
{ "type": "Feature", "properties": { "id": 5}, "geometry": { "type": "LineString", "coordinates": [ [ -74.243246789888346, 40.038535382572938 ], [ -74.243221882547942, 40.038496558418132 ], [ -74.243182498790546, 40.038435169141529 ], [ -74.243137176965064, 40.038364523771932 ], [ -74.243057495263045, 40.038240319569326 ], [ -74.242984178076739, 40.038126035633333 ], [ -74.242983803896664, 40.038125452375041 ], [ -74.242970932683164, 40.03810547276553 ], [ -74.242927580863451, 40.038038178902433 ] ] } }
]
}
let width = 900,
height = 500,
initialScale = 1 << 17,
initialCenter = [-74.20465,39.98783]
let svg = d3.select('body')
.append('svg')
.attr('height', height)
.attr('width', width)
let map = svg.append('g')
let images = map.append('g')
.attr('pointer-events', 'none')
.selectAll('image');
let glines = map.append('g')
let lines = glines.append('g')
let projection = d3.geoMercator()
.scale(initialScale)
.center(initialCenter)
.translate([width / 2, height / 2])
let path = d3.geoPath(projection)
const tile = d3.tile()
.extent([[0, 0], [width, height]])
let zoom = d3.zoom()
.on('zoom', () => zoomed(d3.event.transform))
svg.call(zoom)
function zoomed(transform) {
const tiles = tile(transform);
lines.attr('transform', transform.toString())
images = images.data(tiles, d => d)
.join('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr('y', ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
function drawMap(data) {
let tiles = tile
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]))();
lines.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('class', 'line')
.attr('d', path)
images = images.data(tiles, d => d)
.enter()
.append('image')
.attr('xlink:href', d => 'https://tiles.wmflabs.org/bw-mapnik/' + d[2] + '/' + d[0] + '/' + d[1] + '.png')
.attr('x', d => (d[0] + tiles.translate[0]) * tiles.scale)
.attr('y', d => (d[1] + tiles.translate[1]) * tiles.scale)
.attr('width', tiles.scale)
.attr('height', tiles.scale);
}
d3.json('test.geojson').then(drawMap)
我找到了一种更简单的方法,可以使用 D3 + Leaflet 在底图上放置线条。请参阅 https://observablehq.com/@sfu-iat355/intro-to-leaflet-d3-interactivity。创造奇迹。