gpt4 book ai didi

javascript - 将圆的半径(以米为单位)缩放到 D3.js d3.geo.mercator map

转载 作者:行者123 更新时间:2023-11-30 00:25:31 25 4
gpt4 key购买 nike

我正在使用 D3.js 和 TopoJSON 库在网页上的小 div 中呈现平面 SVG 世界地图。我还获取了一些地理对象(多边形和圆圈),并通过纬度/经度坐标将它们绘制在这张 map 上。这一切似乎都运行良好,但是,我在 map 上绘制的圆形对象包含一个以米为单位的半径元素。我无法找到或弄清楚如何将此测量值适本地转换/缩放到 SVG map 上。任何帮助将不胜感激。

绘制圆圈和设置的代码片段是:

if (formattedGeoObjects[a].shape.indexOf('circle') >= 0) {
//plot point for circle
svg.selectAll('.pin')
.data(formattedGeoObjects).enter().append('circle', '.pin')
.attr({fill: formattedGeoObjects[a].color.toString()})
.attr('r', 5) //formattedGeoObjects[a].radius is in meters
.attr('transform', 'translate(' +
projection([
formattedGeoObjects[a].location[0],
formattedGeoObjects[a].location[1]
]) + ')'
);
}

精简版代码的 JSFiddle 链接:https://jsfiddle.net/vnrL0fdc/7/

这里是完整的代码供引用...

完成大部分工作的函数:

setupMap: function(mapJson, theElement, geoObject, colorCb, normalizeCb) {
var width = 200;
var height = 120;

//define projection of spherical coordinates to Cartesian plane
var projection = d3.geo.mercator().scale((width + 1) / 2 / Math.PI).translate([width / 2, height / 2]);

//define path that takes projected geometry from above and formats it appropriately
var path = d3.geo.path().projection(projection);

//select the canvas-svg div and apply styling attributes
var svg =
d3.select('#' + theElement + ' .canvas-svg').append('svg')
.attr('width', width)
.attr('height', height)
.attr('class', 'ocean');

//convert the topoJSON back to GeoJSON
var countries = topojson.feature(mapJson, mapJson.objects.countries).features;

//give each country its own path element and add styling
svg.selectAll('.countries')
.data(countries).enter().append('path')
.attr('class', 'country')
.attr('d', path);

//add borders around all countries with mesh
svg.append('path')
.datum(topojson.mesh(mapJson, mapJson.objects.countries, function() {
return true;
}))
.attr('d', path)
.attr('class', 'border');

//if shape data exists, draw it on the map
if (geoObject !== null && geoObject.length !== 0) {
//normalize geoObject into format needed for d3 arc functionality and store each shapes color
var formattedGeoObjects = normalizeCb(geoObject, colorCb);

for (a = 0; a < formattedGeoObjects.length; a++) {
if (formattedGeoObjects[a].shape.indexOf('polygon') >= 0) {
for (b = 0; b < formattedGeoObjects[a].lines.length; b++) {
//plot point for polygon
svg.selectAll('.pin')
.data(formattedGeoObjects).enter().append('circle', '.pin')
.style({fill: formattedGeoObjects[a].color.toString()}).attr('r', 2)
.attr('transform', 'translate(' +
projection([
formattedGeoObjects[a].lines[b].coordinates[0][0],
formattedGeoObjects[a].lines[b].coordinates[0][1]
]) + ')'
);
}
//draw lines for polygon
svg.append('g').selectAll('.arc')
.data(formattedGeoObjects[a].lines).enter().append('path')
.attr({d: path})
.style({
stroke: formattedGeoObjects[a].color.toString(),
'stroke-width': '1px'
});
}
if (formattedGeoObjects[a].shape.indexOf('circle') >= 0) {
//plot point for circle
svg.selectAll('.pin')
.data(formattedGeoObjects).enter().append('circle', '.pin')
.attr({fill: formattedGeoObjects[a].color.toString()})
.attr('r', 5)
.attr('transform', 'translate(' +
projection([
formattedGeoObjects[a].location[0],
formattedGeoObjects[a].location[1]
]) + ')'
);
}
}
}
}

这是格式化的地理对象的精简版:

[
{
"shape": "polygon0",
"color": "#000000",
"lines": [
{
"type": "LineString",
"coordinates": [
[
-24.9609375,
36.5625
],
[
-24.9609375,
55.1953125
]
]
}
..... more coords
]
},
{
"shape": "polygon1",
"color": "#006600",
"lines": [
{
"type": "LineString",
"coordinates": [
[
-42.1875,
26.3671875
],
[
-71.71875,
7.734375
]
]
}
..... more coordindates
]
},
{
"shape": "circle2",
"color": "#FF0000",
"location": [
13.359375,
31.640625
],
"radius": 1881365.33
}
]

最后,CSS/HTML:

.canvas-svg {
.ocean {
background: #85E0FF;
}
.country {
fill: #FFFFFF;
}
.border {
fill: none;
stroke: #777;
stroke-width: .5;
}
}

<div class="canvas-svg"></div>

最佳答案

我的一位同事向我展示了一种更简单的方法来帮助我(仅供引用 - 圆心的纬度/经度已经更新)。在 Canvas 上绘制两个点并计算距离以找到比例尺是有效的并且是准确的 - 但是有一种更简单的方法可以使用图像中的总像素和世界的总面积,代码片段和下面的 JSFiddle :

var width = 200;
var height = 120;

//variables for scaling circle radius
var totPixels = (width * height);
var totWorldMeters = 510000000000;
var metersPerPixel = (totWorldMeters / totPixels);
var scaledRadius;

//scale the radius given in meters to pixels on the map
scaledRadius = (100 * (formattedGeoObjects[a].radius / metersPerPixel));
if(scaledRadius < 2) {
scaledRadius = 2;
}

工作 JSFiddle:https://jsfiddle.net/vnrL0fdc/15/

关于javascript - 将圆的半径(以米为单位)缩放到 D3.js d3.geo.mercator map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31573480/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com