我正在研究地图上的聚类点(纬度/经度)。 是否有关于快速且可扩展的合适算法的建议?

更具体地说,我有一系列的纬度/经度坐标和一个地图视口。 我试图将靠近的点聚在一起以消除混乱。

我已经有解决问题的方法( 请参阅此处 ),只是我想知道是否有任何形式的算法可以有效地解决问题。

===============>>#1 票数:6 已采纳

对于虚拟地球应用程序,我使用了此处描述的群集。 闪电般快速且易于扩展。

===============>>#2 票数:5

Google Maps Hacks上有一个hack, “ Hack 69.高缩放级别的群集标记”

另外,请参阅Wikipedia上的聚类算法

===============>>#3 票数:4

您可以使用QuadTile方案查看所有点的索引,然后根据比例在四边形分割中进一步缩小。 这样,所有相似位置的点将在索引中彼此靠近,从而可以有效地进行聚类。

QuadTiles是Morton Codes的示例,该Wikipedia文章中链接了一个python示例,可能会有所帮助。

===============>>#4 票数:1

我查看了各种库,发现它们是如此复杂以至于无法理解一个单词,所以我决定制作自己的聚类算法

Java代码到了

static int OFFSET = 268435456;
    static double RADIUS = 85445659.4471;
    static double pi = 3.1444;

public static double lonToX(double lon) {
        return Math.round(OFFSET + RADIUS * lon * pi / 180);
    }

    public static double latToY(double lat) {
        return Math.round(OFFSET
                - RADIUS
                * Math.log((1 + Math.sin(lat * pi / 180))
                        / (1 - Math.sin(lat * pi / 180))) / 2);
    }

//计算特定缩放级别下两个拖拉长点之间的像素距离

    public static int pixelDistance(double lat1, double lon1, double lat2,
            double lon2, int zoom) {
        double x1 = lonToX(lon1);
        double y1 = latToY(lat1);

        double x2 = lonToX(lon2);
        double y2 = latToY(lat2);

        return (int) (Math
                .sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1 - y2), 2))) >> (21 - zoom);
    }

//实际计算聚类的主要函数1.将经纬度长点的ArrayList迭代为length。 2.内部循环从i + 1位置迭代同一arraylist的副本,即保留顶部循环的索引3.将第0个元素视为质心,并比较所有其他点(如果它们的像素距离非常小),将其添加到集群4。从顶部arraylist中删除所有元素,并复制已形成集群5的arraylist,通过从0重新初始化索引来重新启动该过程; 6如果选择的质心没有聚类,则不会删除该元素

static ArrayList<Cluster> cluster(ArrayList<Marker> markers, int zoom) {

        ArrayList<Cluster> clusterList = new ArrayList<Cluster>();

        ArrayList<Marker> originalListCopy = new ArrayList<Marker>();

        for (Marker marker : markers) {
            originalListCopy.add(marker);
        }

        /* Loop until all markers have been compared. */
        for (int i = 0; i < originalListCopy.size();) {

            /* Compare against all markers which are left. */

            ArrayList<Marker> markerList = new ArrayList<Marker>();
            for (int j = i + 1; j < markers.size();) {
                int pixelDistance = pixelDistance(markers.get(i).getLatitude(),
                        markers.get(i).getLongitude(), markers.get(j)
                                .getLatitude(), markers.get(j).getLongitude(),
                        zoom);

                if (pixelDistance < 40) {

                    markerList.add(markers.get(i));
                    markerList.add(markers.get(j));

                    markers.remove(j);

                    originalListCopy.remove(j);
                    j = i + 1;
                } else {
                    j++;
                }

            }

            if (markerList.size() > 0) {
                Cluster cluster = new Cluster(clusterList.size(), markerList,
                        markerList.size() + 1, originalListCopy.get(i)
                                .getLatitude(), originalListCopy.get(i)
                                .getLongitude());
                clusterList.add(cluster);
                originalListCopy.remove(i);
                markers.remove(i);
                i = 0;

            } else {
                i++;
            }

            /* If a marker has been added to cluster, add also the one */
            /* we were comparing to and remove the original from array. */

        }
        return clusterList;
    }

Just pass in your array list here containing latitude and longitude

then to display clusters
here goes the function


@Override
    public void onTaskCompleted(ArrayList<FlatDetails> flatDetailsList) {

        LatLngBounds.Builder builder = new LatLngBounds.Builder();

        originalListCopy = new ArrayList<FlatDetails>();
        ArrayList<Marker> markersList = new ArrayList<Marker>();
        for (FlatDetails detailList : flatDetailsList) {

            markersList.add(new Marker(detailList.getLatitude(), detailList
                    .getLongitude(), detailList.getApartmentTypeString()));

            originalListCopy.add(detailList);

            builder.include(new LatLng(detailList.getLatitude(), detailList
                    .getLongitude()));

        }

        LatLngBounds bounds = builder.build();
        int padding = 0; // offset from edges of the map in pixels
        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);

        googleMap.moveCamera(cu);

        ArrayList<Cluster> clusterList = Utils.cluster(markersList,
                (int) googleMap.getCameraPosition().zoom);

        // Removes all markers, overlays, and polylines from the map.
        googleMap.clear();

        // Zoom in, animating the camera.
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(previousZoomLevel),
                2000, null);

        CircleOptions circleOptions = new CircleOptions().center(point) //
                // setcenter
                .radius(3000) // set radius in meters
                .fillColor(Color.TRANSPARENT) // default
                .strokeColor(Color.BLUE).strokeWidth(5);

        googleMap.addCircle(circleOptions);

        for (Marker detail : markersList) {

            if (detail.getBhkTypeString().equalsIgnoreCase("1 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk1)));
            } else if (detail.getBhkTypeString().equalsIgnoreCase("2 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk_2)));

            }

            else if (detail.getBhkTypeString().equalsIgnoreCase("3 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk_3)));

            } else if (detail.getBhkTypeString().equalsIgnoreCase("2.5 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk2)));

            } else if (detail.getBhkTypeString().equalsIgnoreCase("4 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk_4)));

            } else if (detail.getBhkTypeString().equalsIgnoreCase("5 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk5)));

            } else if (detail.getBhkTypeString().equalsIgnoreCase("5+ BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk_5)));

            }

            else if (detail.getBhkTypeString().equalsIgnoreCase("2 BHK")) {
                googleMap.addMarker(new MarkerOptions()
                        .position(
                                new LatLng(detail.getLatitude(), detail
                                        .getLongitude()))
                        .snippet(String.valueOf(""))
                        .title("Flat" + flatDetailsList.indexOf(detail))
                        .icon(BitmapDescriptorFactory
                                .fromResource(R.drawable.bhk_2)));

            }
        }

        for (Cluster cluster : clusterList) {

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inMutable = true;
            options.inPurgeable = true;
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
                    R.drawable.cluster_marker, options);

            Canvas canvas = new Canvas(bitmap);

            Paint paint = new Paint();
            paint.setColor(getResources().getColor(R.color.white));
            paint.setTextSize(30);

            canvas.drawText(String.valueOf(cluster.getMarkerList().size()), 10,
                    40, paint);

            googleMap.addMarker(new MarkerOptions()
                    .position(
                            new LatLng(cluster.getClusterLatitude(), cluster
                                    .getClusterLongitude()))
                    .snippet(String.valueOf(cluster.getMarkerList().size()))
                    .title("Cluster")
                    .icon(BitmapDescriptorFactory.fromBitmap(bitmap)));

        }

    }




ANY QUESTIONS OR DOUBTS PLEASE ASK WILL CLEAR THEM ALL ...........THANKS

  ask by Codebeef translate from so

未解决问题?本站智能推荐:

1回复

Web导航模式挖掘/网络聚类算法/ Web流量聚类方法

我有以下问题: 我有一个表示为顶点v0,v1,...,vN的网页列表。 我有g0,g1,...,gM图,这些图具有边缘列表,这些边缘列表显示用户在访问网站期间访问的页面,例如: g0:(v3,v44); (v44,v5) g1:(v3,v44); (v44,v5
2回复

高效的动态聚类[关闭]

我有一组来自单位间隔的数据点(即带有数值的一维数据集)。 我在线上收到一些其他数据点,而且某些数据点的值可能会动态变化。 我正在寻找一种可以有效处理这些问题的理想聚类算法。 我知道顺序k均值聚类可以应对新实例的添加,并且我认为只需稍作修改即可使用动态实例值(即,首先从各个聚类中获取经过
4回复

具有未知数量的簇的无监督聚类

我有三个维度的大量向量。 我需要基于欧几里德距离对这些进行聚类,使得任何特定聚类中的所有向量彼此之间的欧几里德距离小于阈值“T”。 我不知道有多少个集群存在。 最后,可能存在不属于任何聚类的个体向量,因为其欧氏距离不小于空间中任何向量的“T”。 这里应该使用哪些现有的算法/方法?
2回复

算法:了解两条线图何时相似

我正在尝试开发一个能够理解两个线图相似的​​脚本(它们具有相似的方向或相似的值)。 例如,假设我有两个数组: 正如您所看到的,它们的增长和价值都非常相似。 目前,我已经找到了一个使用DTW算法的完美工作解决方案。 问题是DTW有一个“ 训练部分 ”非常快(我只需要存储很多线
4回复

如何分类但不使用分类或聚类算法?

我有一个爬虫程序,每天存储来自7家差异新闻社的体育数据。 它每天存储约1200个体育新闻。 我想将过去两天的新闻分类为子类别。 因此,每两天我都会有大约2400个恰好适合这些日子的新闻,而且他们的许多主题都在谈论同一事件。 例如: 70条新闻正在谈论Brad Keselowsk
2回复

用scikit选择层次凝聚聚类中的聚类数

关于确定数据集中群集数量的维基百科文章表明,在使用层次聚类时,我不需要担心这样的问题。 然而,当我尝试使用scikit-learn的凝聚聚类时,我发现我必须将聚类的数量作为参数“n_clusters”提供 - 没有它我得到两个聚类的硬编码默认值。 在这种情况下,如何为数据集选择正确数量的聚类
2回复

大多数相互远离的k元素(聚类?)

我有一个简单的机器学习问题: 我有n(~110)个元素,以及所有成对距离的矩阵。 我想选择最远的10个元素。 也就是说,我想 我的距离度量是对称的并且尊重三角不等式。 我可以使用什么样的算法? 我的第一直觉是做以下事情: 将n个元素聚类为20个聚类。
1回复

如何使用增长神经气体进行聚类?

我知道算法是如何工作的,但我不确定它是如何确定聚类的。 基于图像,我猜它将所有通过边连接的神经元看作一个簇。 因此,您可能有两组神经元,每组都连接在一起。 但是真的吗? 我也想知道...... GNG真的是一个神经网络吗? 它没有传播函数或激活函数或加权边..它不只是一个图形?
2回复

完全基于实体相似性的无监督聚类

我正在尝试群集多个实体。 我拥有的唯一度量标准是一个实体与另一个实体之间的相似性。 (0-1浮动) 谁能想到可以实现此目标的任何聚类算法? 我很欣赏它将返回模糊组。 与目前按编程方式估算组相比,这仍然是一个更好的解决方案。
1回复

根据已知的位置名称对蜂窝塔ID进行聚类

我是数据挖掘的新手,我试图弄清楚如何对蜂窝塔ID进行聚类以从已知的位置标签(家庭,工作,其他地方,无信号)找到其位置。 我有一个用户A的位置驱动的数据集,其中包含cellID(检测到的塔楼的唯一ID),开始时间(它检测到特定塔楼的日期和时间),结束时间(连接到其他塔楼的最后日期和时间),地