2008-09-16 8 views
22

지도에서 클러스터링 포인트를 찾고 있습니다 (위도/경도). 신속하고 확장 가능한 적합한 알고리즘에 대한 권장 사항이 있습니까?매핑 응용 프로그램 용 클러스터링 알고리즘


@Gilligan : 예 - 일련의 위도/경도 및지도 뷰포트가 있습니다. 난 혼란을 제거하기 위해 함께 가까운 지점을 클러스터에 노력하고있어.

나는 문제를 효율적으로 해결하는 정식 알고리즘이 있는지 궁금하다. (see here) 이미 문제에 대한 해결책이있다.

+0

을 삭제되지 않습니다 어떤 클러스터가없는 경우 6은 위도와 경도에 의해 주어진 물리적 위치를 기반으로 클러스터링? –

+0

달성하고자하는 것을 보여주는 코드를 게시 할 수 있습니까? 나는 당신이 정확히 "클러스터링 (clustering)"을 의미하는지 혼란 스럽습니다. 당신은 세계의지도에 그 계획을 세우고 있습니까? – Gilligan

답변

6

가상 어플 리케이션의 경우 클러스터링을 사용했습니다. here. 번개처럼 빠르고 쉽게 확장 할 수 있습니다.

4

QuadTile 구성표를 사용하여 모든 포인트를 인덱싱 한 다음 눈금을 기준으로 볼 때 쿼드 스플릿을 따라 내려갈 수 있습니다. 비슷한 위치에있는 모든 점들은 인덱스에서 서로 가깝게 위치하므로 효율적으로 클러스터링을 수행 할 수 있습니다.

QuadTiles는 Morton Codes의 예이며 도움이 될 수있는 위키 피 디아 문서에서 링크 된 python 예제가 있습니다.

1

나는 다양한 라이브러리를 쳐다 보면서 말을 이해할 수 없었다 그들이 너무 복잡 발견은 그래서 //

여기 자바

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가 길이만큼 반복됩니다. 2. 동일한 루프의 동일한 루프의 복사본을 i + 1 위치에서 반복한다. 즉, 상단 루프의 인덱스를 남긴다. 3. 픽셀 거리가 매우 적 으면 0 번째 요소가 중심점의 중심으로 간주되고 다른 모든 점이 비교된다. 클러스터에 넣으십시오 4. 클러스터를 형성 한 상단 arraylist 및 copy arraylist에서 모든 요소를 ​​제거하십시오. 0125 0에서 인덱스를 다시 초기화하여 프로세스를 다시 시작하십시오. 선택 중심은 그 요소가

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 
+0

모든 문자 explaination하시기 바랍니다? –

+0

코드 만 대답하는 것은 일반적으로 권장하지 않습니다 ...이 코드를 사용하는 방법에 대한 자세한 정보/문제 해결 방법을 포함하십시오. –

+0

안녕하세요 Parag와 Coley Brigman 코드에 인라인 코멘트가 있습니다.너희들은 나에게 exacltly 나에게 말해 줄 수 있겠 니? 내가 설명해주기를 바란다. – user1530779