# 如何圈出某点周边半径2公里的圆(用百度地图)?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# 如何圈出某点周边半径2公里的圆(用百度地图)?相关的知识,希望对你有一定的参考价值。

参考技术A 标签(空格分隔): 技术 解决方案 地图

如何圈出某点周边半径2公里的圆(用百度地图)?
解决的问题
第一步,打开百度地图
第二步,定位到希望搜索的城市
第三步,定位一个点
第四步,搜附近
第五步,查XX地儿
第六步,调范围
第七步,使用

工作中遇到一个问题,先用笨办法,后来搜索,找到“巧”办法,然后整理出来分享给大家。

如标题,在地图上圈出某点周边半径2公里的圆。
用百度地图搜索周边的功能解决。
具体方法步骤:

例图:搜索“保定市”

例图:搜索“乒乓球训练基地报名处”

在显示的地标点上,(红标最根部)点击右键,选择在此点附近查找

输入一个子虚乌有的地方,或者很少的地儿,例:输入“小苗”,点击搜索。(你也可以搜“中南海”,我想除了北京,别的地儿敢这么叫的不多。)

你会看到一个半径1公里(1000米)的蓝色的圆,最右边有个拖动块,可以调整搜索范围,拖动到2公里(2000米),或者你需要的范围。

然后就没有然后了……你可以在此范围内找地方,放大缩小地图,整个范围截图等等。

截图我用的是:PicPick,简单好用。

安利一下我的全部软件工具库,有需要的自己看。
工具、方法“控”的不吐不快 - 幕布(不定时更新)
https://mubu.com/doc/explore/11109

如何在世界地图上准确地绘制半径以公里为单位的圆

【中文标题】如何在世界地图上准确地绘制半径以公里为单位的圆【英文标题】:How to draw circles with radii given in kilometers accurately on world map 【发布时间】:2018-01-07 08:57:35 【问题描述】:

我在大约以太平洋为中心的世界地图上使用 d3.geo.conicEquidistant() 投影,我的目标是从一点画圈,说明从地图上这一点到特定距离,例如 1000 公里.

在给定特定公里数的情况下,我如何计算正确的投影半径?

这是我的代码示例(是的,它是关于从朝鲜发射的导弹。人为地使用平壤作为发射点 :),基于这个问题:Scale a circle's radius (given in meters) to D3.js d3.geo.mercator map

<!DOCTYPE html>
<meta charset="utf-8">
<style>
path 
  stroke: white;
  stroke-width: 0.25px;
  fill: grey;

circle 
  stroke: red;
  stroke-width: 1px;
  stroke-dasharray: 5;
  fill: transparent;

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v0.min.js"></script>
<script>
var width = 960,
    height = 500;

var projection = d3.geo.conicEquidistant()
    .center([0, 5 ])
    .scale((width + 1) / 2 / Math.PI)//.scale(150)
    .rotate([-160,0]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var path = d3.geo.path()
    .projection(projection);

var g = svg.append("g");

var missiles = [
  
    name: "missile1",
    location:  // appx lat&long of pyongyang
      latitude: 125.6720717, 
      longitude: 39.0292506
    ,
    reach: 1000 //radius of circle in kilometers on map
  ,
    
    name: "missile2",
    location:  // appx lat&long of pyongyang
      latitude: 125.6720717, 
      longitude: 39.0292506
    ,
    reach: 3500 //radius of circle in kilometers on map
  ,
];


// load and display the World
d3.json("https://s3-us-west-2.amazonaws.com/vida-public/geo/world-topo-min.json", function(error, topology) 
    g.selectAll("path")
      .data(topojson.object(topology, topology.objects.countries)
          .geometries)
    .enter()
      .append("path")
      .attr("d", path)
);


svg.selectAll(".pin")
    .data(missiles)
  .enter().append("circle", ".pin")
    .attr("r", scaledRadius)
      /*function(d) 
      return d.reach
      )*/


    .attr("transform", function(d) 
      return "translate(" + projection([
        d.location.latitude,
        d.location.longitude
      ]) + ")"
    )

</script>
</body>
</html>

我查看了这个答案,在上面进行了尝试,但不太能够将它应用到我的代码中(老实说,我对 d3 很陌生,可能有一些非常明显的错误): https://***.com/a/31616927/4623519

另一个问题:这个解决方案是特定于墨卡托投影的吗?

(让我们忽略我们确实需要在此投影中隐藏南极洲。)

【问题讨论】:

你能把我们链接到工作代码,或者用jsfiddle这个吗? 这是我在用 Andrew 的回答更改我的代码后所做的一个 jfiddle:jsfiddle.net/y8qn8tr1 - 出于某种原因,世界地图路径没有显示在小提琴中...... 访问geojson时尝试https://而不是http://:jsfiddle.net/38he3mt9 啊,太好了,谢谢! 【参考方案1】:

有两种方法可以实现这一点。

其中一个(更简单的选项)使用 d3 的 geoCircle 功能创建地理循环特征:

var circle = d3.geoCircle().center([x,y]).radius(r);

为此,x 和 y 是以度为单位的中心点,而 r 是以度为单位的圆的半径。为了找到以米为单位的圆的半径,我们需要将米转换为度 - 如果我们假设地球是圆形的,这是最简单的(地球只是略呈椭圆形,因此这是一个高达 0.3% 的诱导误差,但即使使用椭球体,地球实际上更像马铃薯形状,因此也会产生误差)。使用 6,371 公里的平均半径,我们可以得到一个粗略的公式,例如:

var circumference = 6371000 * Math.PI * 2;

var angle = distance in meters / circumference * 360;

var circle = d3.geoCircle().center([x,y]).radius(angle);

这给了我们类似的东西:

var width = 500;
var height = 300;

var svg = d3.select("body")
  .append("svg")
  .attr("width",width)
  .attr("height",height);
  
var projection = d3.geoAlbers()
  .scale(200)
  .translate([width/2,height/2]);
  
var path = d3.geoPath().projection(projection);

var usa = "type":"FeatureCollection", "features": [
"type":"Feature","geometry":"type":"MultiPolygon","coordinates":[[[[-94.81758,49.38905],[-88.378114,48.302918],[-82.550925,45.347517],[-82.439278,41.675105],[-71.50506,45.0082],[-69.237216,47.447781],[-66.96466,44.8097],[-70.11617,43.68405],[-70.64,41.475],[-73.982,40.628],[-75.72205,37.93705],[-75.72749,35.55074],[-81.49042,30.72999],[-80.056539,26.88],[-81.17213,25.20126],[-83.70959,29.93656],[-89.18049,30.31598],[-94.69,29.48],[-99.02,26.37],[-100.9576,29.38071],[-104.45697,29.57196],[-106.50759,31.75452],[-111.02361,31.33472],[-117.12776,32.53534],[-120.36778,34.44711],[-123.7272,38.95166],[-124.53284,42.76599],[-124.68721,48.184433],[-122.84,49],[-116.04818,49],[-107.05,49],[-100.65,49],[-94.81758,49.38905]]],[[[-155.06779,71.147776],[-140.985988,69.711998],[-140.99777,60.306397],[-148.018066,59.978329],[-157.72277,57.570001],[-166.121379,61.500019],[-164.562508,63.146378],[-168.11056,65.669997],[-161.908897,70.33333],[-155.06779,71.147776]]]],"properties":"name":"United States of America","id":"USA"
];

var circumference = 6371000 * Math.PI * 2;
var angle = 1000000 / circumference * 360;

var circle = d3.geoCircle().center([-100,40]).radius(angle);

svg.append("path")
      .attr("d",path(usa));

svg.append("path")
  .attr("d", path(circle()))
  .attr("fill","steelblue");
  
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"&gt;&lt;/script&gt;

另一种选择是通过自定义函数而不是通过 d3 动态创建 geojson 功能。最简单的方法可能是取一个点,并计算相距 10 度的方位距 x 米的点(对于圆的 36 个点)。这需要使用起点、方位和距离来计算一个点,公式可以在这里找到。不久前,我使用这种方法构建了一个示例 tissot 的指标:Tissot's Indicatrix Bl.ock。

【讨论】:

伟大的安德鲁,谢谢!这非常有帮助。我将我的代码更改为 d3 v4,并且能够像我希望的那样使用第一种更简单的方法来绘制圆圈。无论地图投影如何,这似乎都有效? 6371公里从何而来?我将我编辑的代码作为分析器在这里。 我使用了 wikipedia 提供的平均地球半径,尽管您可以使用 WGS84 规范作为地球的长轴和短轴(或任何其他基准),并取两者的平均值相当接近地球半径。【参考方案2】:

基于 Andrew 的回答,这是我解决问题的方法:

添加样式,将我的代码更改为 d3 v4:

</!DOCTYPE html>
<html>
<head>
    <title></title>
    <style>
        path 
      stroke: white;
      stroke-width: 0.25px;
      fill: grey;
    
    .circle 
      stroke: red;
      stroke-width: 1px;
      stroke-dasharray: 5;
      fill: transparent;
    
    </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

d3 脚本:

var width = 1200;
var height = 400;

var svg = d3.select("body")
  .append("svg")
  .attr("width",width)
  .attr("height",height);

使用圆锥等距投影:

var projection = d3.geoConicEquidistant()
    .center([0, 20])
    .scale((width + 1) / 2 / Math.PI)
    .rotate([-140,0]);

var path = d3.geoPath()
    .projection(projection);

根据安德鲁的回答创建圆圈,一个半径为 1000 公里,另一个半径为 3500 公里。我猜这些可以更好地排列到列表/对象中。

var circumference = 6371000 * Math.PI * 2;

var angle1 = 1000000 / circumference * 360;
var missile1 = d3.geoCircle().center([125.6720717,39.0292506]).radius(angle1);

var angle2 = 3500000 / circumference * 360;
var missile2 = d3.geoCircle().center([125.6720717,39.0292506]).radius(angle2);

加载和显示世界:

var url = "http://enjalot.github.io/wwsd/data/world/world-110m.geojson";
//display the world
    d3.json(url, function(err, geojson) 
      svg.append("path")
        .attr("d", path(geojson));
//append the circles
      svg.append("path")
        .attr("d", path(missile1()))
        .attr("class","circle");
      svg.append("path")
        .attr("d", path(missile2()))
        .attr("class","circle");
   );

编辑:将 https 添加到 json 文件并更改代码,以便在世界地图上方绘制圆圈。我在这里有一个工作 jfiddle:https://jsfiddle.net/y8qn8tr1/2/

【讨论】:

答案中的问题通常很少得到回应 - 仅限于 cmets,并且受众有限。尝试https:// 为小提琴中的geojson,世界的绘制发生在绘制其他所有内容之后 - d3.json 是异步的,要么在回调中附加圆圈,要么使用按指定顺序附加的 g 元素(在 d3 之外.json 回调)并将特征附加到这些 g 元素(从而对它们进行排序)。 再次感谢!我用 https 更新了 jfiddle,所以它现在可以工作了。这是我的第一个问题,仍然试图弄清楚后续问题的做法是什么,我有点不确定我是否应该发布新答案或编辑原始答案并将新问题作为 cmets。也许编辑原件更好?但这可能与我最初的问题无关。 如果您有新的/不同的问题,请单独提出。如果您认为它会添加上下文,您可以随时链接到此问题。

以上是关于# 如何圈出某点周边半径2公里的圆(用百度地图)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在世界地图上准确地绘制半径以公里为单位的圆

电脑上百度地图我怎么确定一个地点的范围呢

【在线等】怎么在百度地图上查找方圆多少公里内的地方

Android POI 百度地图——周边检索

百度地图缩放问题

Android:如何将地图视图的缩放级别设置为当前位置周围 1 公里半径?