--------------------------高难度算法-------------------------------

by_封爱 版主 2016-12-13 10:19:53
加精
标题党


需求就是有一大堆GPS数据.要show在map上,但是很多点重叠或者很近 导致map上面的point无法点击或者看不到.

要求实现的就是把数据点做偏差,让所有的point都能被看到而且被点击.(需求无法更改)

那么我只能从数据上下手.


//实体
public class demo
{
public int id { get; set; }--用于显示的时候看,.无实际意义.
public double lat { get; set; }
public double lng { get; set; }
}
//插入测试数据
var array = new List<demo>();
array.Add(new demo() { id = 1, lat = 30.000000, lng = 120.0001 });
array.Add(new demo() { id = 2, lat = 30.000000, lng = 120.0002 });
array.Add(new demo() { id = 3, lat = 30.000000, lng = 120.0003 });
array.Add(new demo() { id = 4, lat = 30.000000, lng = 120.0004 });
array.Add(new demo() { id = 5, lat = 30.000000, lng = 120.0005 });


其实对于point 我还有一个网上找的方法.来计算2个point之间的距离 如下.

public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
{
try
{
var b = Math.PI / 180;
var c = Math.Sin((lat2 - lat1) * b / 2);
var d = Math.Sin((lng2 - lng1) * b / 2);
var a = c * c + d * d * Math.Cos(lat1 * b) * Math.Cos(lat2 * b);
return 12756274 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
}
catch (Exception)
{
return 0;
}
}


我大概看了下经纬度的0.0001 大概就是10米..那么我们就暂定认为上面的测试数据 每个点 都相距10米.

但是我的需求 是最少20米. 那么我的方法如下


var q = array.OrderBy(d => d.lng).ToList();
for (int i = 0; i < q.Count; i++)
{
var 当前 = q[i];
if (i != 0)
{
var 上一个 = q[i - 1];
var m = Common.GPSHelper.GetDistance(当前.lat, 当前.lng, 上一个.lat, 上一个.lng);
if (m < 20)
{
q[i].lng = 上一个.lng + 0.0002;
}
}
}
Console.WriteLine(q.ToJson(true));

也就是 从第二个开始判断.如果跟上面的点相距小于20米.那么我当前的纬度=上一个纬度+0.0002

从上面的测试数据 我可以得到.

0001 0003 0005 0007 0009 符合我的要求.

但是如果我在测试数据在加上一条


array.Add(new demo() { id = 6, lat = 30.000000, lng = 120.0006 });


这个时候 这条数据 是跟上面id=5的去对比..但是这个时候 id=5 这条数据 已经是0009了 0006跟0009相差30米.符合条件.

但是在之前 已经有0005 跟 0007 .那么还是失败了..

所以这个计算方式还是有问题..

那么最终我要问的问题大概就是这样.

在一大堆上面的数据中..要求"计算"后 任意2点的lng相减必须大于0.0002 如果有不大于的 一直加0.0002 直到死亡...
...全文
4676 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2016-12-26
  • 打赏
  • 举报
回复
引用 43 楼 winxpliyou 的回复:
[quote=引用 33 楼 caozhy 的回复:] [quote=引用 32 楼 wanghui0380 的回复:] 如果你能想象一下,俺们的地球半径”胖“了10米,那么经纬度差1度的点投影上间隔”大“了几米? 所以让他看起来距离大点,只需要简单的在一个假想的”肥“了10米的”地球“上投影一遍,这就是简单数学问题了
由于气候变暖,地球的大气层真的变胖了。后果就是每天的长度在拉长。问题是秒的长度是固定的,每天的秒数也是固定的。只好无可预见性的不断插入闰秒,这给有高精度历法和计时需求的程序的编写增加了很多复杂度。[/quote] 一本正经的胡说八道。。闰秒,是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中(也可能在季末)对协调世界时增加或减少1秒的调整。由于地球自转的不均匀性和长期变慢性(主要由潮汐摩擦引起的),会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒); 闰秒一般加在公历年末或公历六月末。[/quote] 请问我说的错在哪里?
winxpliyou 2016-12-26
  • 打赏
  • 举报
回复
引用 33 楼 caozhy 的回复:
[quote=引用 32 楼 wanghui0380 的回复:] 如果你能想象一下,俺们的地球半径”胖“了10米,那么经纬度差1度的点投影上间隔”大“了几米? 所以让他看起来距离大点,只需要简单的在一个假想的”肥“了10米的”地球“上投影一遍,这就是简单数学问题了
由于气候变暖,地球的大气层真的变胖了。后果就是每天的长度在拉长。问题是秒的长度是固定的,每天的秒数也是固定的。只好无可预见性的不断插入闰秒,这给有高精度历法和计时需求的程序的编写增加了很多复杂度。[/quote] 一本正经的胡说八道。。闰秒,是指为保持协调世界时接近于世界时时刻,由国际计量局统一规定在年底或年中(也可能在季末)对协调世界时增加或减少1秒的调整。由于地球自转的不均匀性和长期变慢性(主要由潮汐摩擦引起的),会使世界时(民用时)和原子时之间相差超过到±0.9秒时,就把世界时向前拨1秒(负闰秒,最后一分钟为59秒)或向后拨1秒(正闰秒,最后一分钟为61秒); 闰秒一般加在公历年末或公历六月末。
qq_36834695 2016-12-23
  • 打赏
  • 举报
回复
围观一下
qq_37151173 2016-12-23
  • 打赏
  • 举报
回复
66666666666666
htcyrylcmj0415 2016-12-23
  • 打赏
  • 举报
回复
之前的有用百度地图做过,也遇到一样的问题 当时我是在坐标加上随机的正负坐标,实现在原点的周围标点 部分代码如下

				if(px==1){
					x = parseFloat(x*q)+(k*w);
// 					alert(x);
					if(py==1){
						y = parseFloat(y*q)+(l*w);
					}else{
						y = parseFloat(y*q)-(l*w);
					}
				}else{
					x = parseFloat(x*q)-(k*w);
					if(py==1){
						y = parseFloat(y*q)+(l*w);
					}else{
						y = parseFloat(y*q)-(l*w);
					}
				}
C#我就不知道咯,希望有点参考价值
阿母 2016-12-22
  • 打赏
  • 举报
回复
mnxm 2016-12-21
  • 打赏
  • 举报
回复
这种坐标偏移的做法感觉好蠢 如果点过于密集,导致有的点偏移很远,这样也没问题?
闭包客 2016-12-20
  • 打赏
  • 举报
回复
引用 33 楼 caozhy 的回复:
[quote=引用 32 楼 wanghui0380 的回复:] 如果你能想象一下,俺们的地球半径”胖“了10米,那么经纬度差1度的点投影上间隔”大“了几米? 所以让他看起来距离大点,只需要简单的在一个假想的”肥“了10米的”地球“上投影一遍,这就是简单数学问题了
由于气候变暖,地球的大气层真的变胖了。后果就是每天的长度在拉长。问题是秒的长度是固定的,每天的秒数也是固定的。只好无可预见性的不断插入闰秒,这给有高精度历法和计时需求的程序的编写增加了很多复杂度。[/quote] 不明觉厉。
threenewbee 2016-12-20
  • 打赏
  • 举报
回复
引用 32 楼 wanghui0380 的回复:
如果你能想象一下,俺们的地球半径”胖“了10米,那么经纬度差1度的点投影上间隔”大“了几米? 所以让他看起来距离大点,只需要简单的在一个假想的”肥“了10米的”地球“上投影一遍,这就是简单数学问题了
由于气候变暖,地球的大气层真的变胖了。后果就是每天的长度在拉长。问题是秒的长度是固定的,每天的秒数也是固定的。只好无可预见性的不断插入闰秒,这给有高精度历法和计时需求的程序的编写增加了很多复杂度。
robake 2016-12-20
  • 打赏
  • 举报
回复
引用 35 楼 hemowolf 的回复:
楼主是什么地图? 据我所知,百度、高德地图都有现成的功能,把很多个距离相近的点集成一个,我们项目里手机APP里的地图就有这个功能
那个叫聚合,比如地图显示比例为能显示全国范围的时候,很多城市里的内容就堆一块了,这时候用一个点表示就好,放大地图的时候,再根据精度,显示地图可视区域范围内的点,同时根据点的密集程度,继续使用聚合。 百度地图里有封装好的海量点显示的方式,这个可以参考。我曾经有个项目没有直接使用海量点,是直接使用聚合的方式解决的。 也可以参考一下搜房的地图查找房价功能,这个类似。
小灰狼 2016-12-20
  • 打赏
  • 举报
回复
楼主是什么地图? 据我所知,百度、高德地图都有现成的功能,把很多个距离相近的点集成一个,我们项目里手机APP里的地图就有这个功能
lwq222121 2016-12-14
  • 打赏
  • 举报
回复
感觉,排序后计算每两个之前的距离,小于20的加够20就行了吧?
wanghui0380 2016-12-14
  • 打赏
  • 举报
回复
如果你能想象一下,俺们的地球半径”胖“了10米,那么经纬度差1度的点投影上间隔”大“了几米? 所以让他看起来距离大点,只需要简单的在一个假想的”肥“了10米的”地球“上投影一遍,这就是简单数学问题了
lh_qppr 2016-12-14
  • 打赏
  • 举报
回复
按你所说一大堆数据中难免出现 {lat = 30.000000, lng = 120.0001 } {lat = 30.000000, lng = 120.0007 }这种同纬度不同经度的数据。然后想靠水平偏移实现简直了数据量一大。丑先不说。八个方向偏移都不够
夏天的枫 2016-12-13
  • 打赏
  • 举报
回复
想过一个最小外接圆,但是计算量还是挺复杂,如果有N个点,得计算N!次距离,并且要有针对性的偏移(想到的是通过两点之间的斜率来偏,然后继续循环)。。。不过感觉计点少的时候没得问题,多了就不得了了
闭包客 2016-12-13
  • 打赏
  • 举报
回复
这不就是支付宝的那个【到位】吗? 一屏显示几十坐标,就是卡住了,更别说点击了。 这种问题程序员也很为难,坐标做了偏差,也就是不准确了。到时候还是程序员的错。
Poopaye 2016-12-13
  • 打赏
  • 举报
回复
人家做地图的都会在边上额外加个列表的
xuzuning 2016-12-13
  • 打赏
  • 举报
回复
当向结果序列加入一个节点时,要将该节点与结果序列中的每一的节点进行比较 从而判定是否允许该节点加入,显然计算量是比较大的 可将靶区从现在的 圆形 改为 矩形,只需检查 经(纬)度差是否大于 0.0001 * n 只做减法,速度应该就不是问题了
  • 打赏
  • 举报
回复
“直到死亡...”是什么鬼? 写一个for循环然后比较当前点是否>=“前一个点+0.00002”就可以了,这可不叫做什么“高难度算法”,这是没有学过专业而仅仅学编程培训的人也应该了解的——简单的for循环流程图。 你学会画流程图,才能编程。我看到的问题不是什么“算法”问题,而是基本的“不会循环语句流程设计”问题。
  • 打赏
  • 举报
回复
List<int> list = new List<int>();
list.Add(1);
list.Add(4);
list.Add(6);
list.Add(9);
list = list.OrderBy(i => i).ToList();
for (var i = 1; i < list.Count; i++)
{
    var diff = list[i] - list[i - 1];
    if (diff <= 2)
    {
        list[i] = list[i - 1] + 3;
    }
}

Console.WriteLine(string.Join(",", list));
不过我还是想说只管一个纬度肯定是不对滴
加载更多回复(23)

110,570

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧