Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 映射应用的聚类算法_Algorithm_Machine Learning_Maps_Artificial Intelligence_Cluster Analysis - Fatal编程技术网

Algorithm 映射应用的聚类算法

Algorithm 映射应用的聚类算法,algorithm,machine-learning,maps,artificial-intelligence,cluster-analysis,Algorithm,Machine Learning,Maps,Artificial Intelligence,Cluster Analysis,我正在研究地图上的聚类点(纬度/经度)。有没有关于快速可扩展的合适算法的建议 更具体地说,我有一系列纬度/经度坐标和一个地图视口。我正试图将靠得很近的点进行聚类,以消除混乱 我已经有了这个问题的解决方案(),只是我想知道是否有任何正式的算法可以有效地解决这个问题。Google Maps Hacks在这方面有一个技巧 另外,请参阅。,了解我使用的虚拟地球应用程序集群 . 它的速度非常快,而且易于扩展。您可以使用一个方案为所有点建立索引,然后根据比例进一步向下移动四边形分割。然后,所有位置相似的点将

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

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

我已经有了这个问题的解决方案(),只是我想知道是否有任何正式的算法可以有效地解决这个问题。

Google Maps Hacks在这方面有一个技巧


另外,请参阅。

,了解我使用的虚拟地球应用程序集群
. 它的速度非常快,而且易于扩展。

您可以使用一个方案为所有点建立索引,然后根据比例进一步向下移动四边形分割。然后,所有位置相似的点将在索引中彼此靠近,从而有效地进行聚类


QuadTiles是的一个例子,维基百科文章中链接的python示例可能会有所帮助。

我查看了各种库,发现它们太复杂了,一个词都听不懂,所以我决定自己做一个聚类算法

下面是我的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);
    }
//这将计算特定缩放级别下两个lat long点之间的像素距离

    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.lat long点的ArrayList迭代到长度。 2.内部循环从i+1位置(即离开顶部循环的索引)迭代同一arraylist的副本 3.第0个元素作为质心的中心,如果其他所有点的像素距离非常小,则将其添加到聚类中 4.从顶部arraylist中删除所有元素并复制已形成群集的arraylist 5通过从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
静态ArrayList群集(ArrayList标记,整数缩放){
ArrayList clusterList=新的ArrayList();
ArrayList originalListCopy=新ArrayList();
用于(标记:标记){
原始复印件。添加(标记);
}
/*循环,直到比较完所有标记*/
对于(int i=0;i0){
Cluster Cluster=新群集(clusterList.size(),markerList,
markerList.size()+1,originalListCopy.get(i)
.getLatitude(),originalListCopy.get(i)
.getLongitude());
clusterList.add(集群);
原件。删除(i);
删除(i);
i=0;
}否则{
i++;
}
/*如果已将标记添加到集群,请同时添加该标记*/
/*我们正在比较并从阵列中删除原始文件*/
}
返回集群列表;
}
只需在此处输入包含纬度和经度的数组列表
然后显示集群
下面是函数
@凌驾
已完成的公用void ontask(ArrayList FlatDetails列表){
LatLngBounds.Builder=新的LatLngBounds.Builder();
originalListCopy=新的ArrayList();
ArrayList markersList=新建ArrayList();
用于(FlatDetails详细列表:flatDetailsList){
添加(新标记)(detailList.getLatitude(),detailList
.getLongitude(),detailList.getApartmentTypeString());
原始列表。添加(详细列表);
builder.include(新板条)(detailList.getLatitude(),detailList
.getLongitude());
}
LatLngBounds bounds=builder.build();
int padding=0;//与贴图边缘的偏移量(以像素为单位)
CameraUpdate cu=CameraUpdateFactory.newLatLngBounds(边界、填充);
谷歌地图。移动摄像机(cu);
ArrayList clusterList=Utils.cluster(markersList,
(int)googleMap.getCameraPosition().zoom);
//从地图中删除所有标记、覆盖和多段线。
googleMap.clear();
//放大,设置摄影机动画。
googleMap.animateCamera(CameraUpdateFactory.zoomTo(先前的ZoomLevel),
2000年,无效);
CircleOptions CircleOptions=新CircleOptions().中心(点)//
//设置中心
.半径(3000)//以米为单位设置半径
.fillColor(Color.TRANSPARENT)//默认值
.strokeColor(颜色.蓝色).strokeWidth(5);
googleMap.addCircle(圆圈选项);
用于(标记详细信息:标记列表){
if(detail.getBhkTypeString().equalsIgnoreCase(“1 BHK”)){
addMarker(新的MarkerOptions()
.职位(
新板条(detail.getLatitude(),detail
.getLongitude())
.snippet(String.valueOf(“”)
.标题(“平面”+平面详图列表索引(详图))
.图标(位图描述符工厂)
.fromResource(R.dra