Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Clustering #198

Merged
merged 56 commits into from

3 participants

@tmcw
Owner

No description provided.

@tmcw
Owner

This needs to be configured per-marker; this doesn't really fix our lack of a marker anchor point.

Anchor points are defined from OSMDroid as "MarkerHotspots". Since we are using Maki as default Markers, the default anchor point should be center-center instead of bottom-center.

That said, Marker is probably not the best place to put this in. We'd be better changing OverlayItem, but since we'll end up getting rid of the Overlay idiom I thought I'd put it in Marker.

src/main/java/com/mapbox/mapboxsdk/views/MapView.java
((120 lines not shown))
+ clusterList.add(m);
+ System.out.println("center for group " + group + " is: " + result);
+ return result;
+ }
+
+
+
+ private double screenX(OverlayItem item){
+ return mProjection.toPixels(item.getPoint(), null).x;
+ }
+
+ private double screenY(OverlayItem item){
+ return mProjection.toPixels(item.getPoint(), null).y;
+ }
+
+ private double dist(double x1, double y1, double x2, double y2){
@tmcw Owner
tmcw added a note

Could use PointF.length(x,y) here

@fdansv
fdansv added a note

Indeed! Didn't know about this class, let me change it.

@fdansv
fdansv added a note

ah hold on... this is a static method to obtain the distance to 0,0... not as straightforward as I thought

@tmcw Owner
tmcw added a note
PointF.length(x2 - x1, y2 - y1);

?

@fdansv
fdansv added a note

eeshh... let's pretend this never happened - 4f6eda1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...src/main/java/com/mapbox/mapboxsdk/views/MapView.java
((10 lines not shown))
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
+import android.view.*;
@tmcw Owner
tmcw added a note

I've been doing the opposite of this - checkstyle & IntelliJ always recommend against .* imports

@fdansv
fdansv added a note

I hadn't really noticed. IDEA does it automatically.

@bleege Owner
bleege added a note

Yeah, IntelliJ by default will allow 5 imports from one package before it'll automatically replace it with a wildcard import. The setting can be adjusted in the Code Style settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -290,6 +277,146 @@ public void loadFromGeoJSONString(String geoJSON) throws JSONException {
GeoJSON.parseString(geoJSON, MapView.this);
}
+// ########################################
+// CLUSTERING-RELATED METHODS
+// They are here temporarily
+// ########################################
@tmcw Owner
tmcw added a note

Can you make notes & todos as checklists in pull requests & as issues in github instead of adding comments like this one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
fdansv added some commits
@fdansv fdansv changes AndroidManifest to declare minimum API verison supported (Gin…
…gerbread)
3fd20b0
@fdansv fdansv adds version check for getting screen width 3b3aa74
@fdansv fdansv fixes URL malformation when no symbol is specified. Ref #203 d45c61b
@fdansv fdansv refactors clustering so that its methods live within the Itemized Ove…
…rlay class instead of the MapView
5a54181
@fdansv fdansv removes all clustering methods from the MapView de6a2cb
@fdansv fdansv adds simple public cluster method to MapView e6ce8f8
@fdansv fdansv adds containsAll to bounding box class 57ce22c
@fdansv fdansv adds method to get max zoom level for bounding box visibility d2d5610
@fdansv fdansv adds default actions on cluster marker tap up (zoom to clustered mark…
…ers extent)
e8edb43
@fdansv fdansv adds getCoordinatesList 9825b77
@fdansv fdansv removes sout 5260c43
@fdansv fdansv Merge branch 'master' into clustering
Conflicts:
	MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/Icon.java
4c19938
@fdansv fdansv changes initial values of max and min coordinates to avoid comparison…
… conflicts
211e9b2
@fdansv fdansv uses zoomToBoundingBox instead of getting bounds zoom manually fd4a78c
@fdansv fdansv removes getBoundsZoom b0d6bd7
@fdansv fdansv Adds ClusterItem as subclass of Marker 639c354
@fdansv fdansv adds cluster circle as an image 4edaf78
@fdansv fdansv adds fallback marker 1c1e333
@fdansv fdansv removes invalidate right after addItem, as remote marker won't be rea…
…dy by then
36be015
@fdansv fdansv sets density of marker bitmaps on load ee46fc8
@fdansv fdansv sets offline marker if no Maki icon is specified f226cdc
@fdansv fdansv refactors to use ClusterItem instead of Marker fa71bd2
@fdansv fdansv not clustering if there's no more than one item in the group 6806460
@fdansv fdansv sets cluster special marker up c259d64
@fdansv fdansv draws the number of clustered items if the item being drawn is a clus…
…ter marker
91eb331
@fdansv fdansv adds prettier constructor to ClusterItem - assumes that it won't have…
… a description nor title
7afa361
@fdansv fdansv re-initializes the cluster list on each cluster call 6ea3cc6
@fdansv fdansv adds a cluster only if the child count is higher than one by default eef3daa
@fdansv fdansv adds method to get all itemized overlays (marker layers) 8ded563
@fdansv fdansv extends clustering to any marker layers apart from the default one f9bbf44
@fdansv fdansv reinits the cluster overlay each time the cluster method is called 3b630f0
@fdansv fdansv adds check to see if this overlay contains clusters, instead of using…
… another subclass
5b45ad5
@fdansv fdansv adds cluster method to setZoom() cfdc1b2
@fdansv fdansv clusters a group of markers only if those markers are not themselves …
…clusters
91b1fb2
@fdansv

@tmcw @incanus @bleege

Merging this to master. There's still to do, but we've got a solid base for clustering here:

cluster

@fdansv fdansv merged commit 5f29a2f into master
@fdansv fdansv deleted the clustering branch
@bleege
Owner

Awesome! Can't wait to play with this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 25, 2014
  1. @fdansv

    adds dist and cluster

    fdansv authored
  2. @fdansv
  3. @fdansv
  4. @fdansv
  5. @fdansv

    adds getGroupSet

    fdansv authored
  6. @fdansv
Commits on Feb 26, 2014
  1. @fdansv
  2. @fdansv

    adds getThreshold

    fdansv authored
  3. @fdansv
  4. @fdansv
  5. @fdansv
  6. @fdansv
  7. @fdansv

    generates marker with cluster

    fdansv authored
Commits on Feb 27, 2014
  1. @fdansv
  2. @fdansv
  3. @fdansv
  4. @fdansv
  5. @fdansv

    sets property on cluster match

    fdansv authored
  6. @fdansv
  7. @fdansv
  8. @fdansv
Commits on Feb 28, 2014
  1. @fdansv
  2. @fdansv
Commits on Mar 3, 2014
  1. @fdansv
  2. @fdansv

    refactors clustering so that its methods live within the Itemized Ove…

    fdansv authored
    …rlay class instead of the MapView
  3. @fdansv
  4. @fdansv
Commits on Mar 5, 2014
  1. @fdansv
  2. @fdansv
  3. @fdansv
  4. @fdansv

    adds getCoordinatesList

    fdansv authored
  5. @fdansv

    removes sout

    fdansv authored
  6. @fdansv

    Merge branch 'master' into clustering

    fdansv authored
    Conflicts:
    	MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/Icon.java
  7. @fdansv
  8. @fdansv
  9. @fdansv

    removes getBoundsZoom

    fdansv authored
Commits on Mar 11, 2014
  1. @fdansv
  2. @fdansv

    adds cluster circle as an image

    fdansv authored
  3. @fdansv

    adds fallback marker

    fdansv authored
  4. @fdansv
  5. @fdansv
  6. @fdansv
  7. @fdansv
  8. @fdansv
  9. @fdansv

    sets cluster special marker up

    fdansv authored
  10. @fdansv
  11. @fdansv

    adds prettier constructor to ClusterItem - assumes that it won't have…

    fdansv authored
    … a description nor title
  12. @fdansv
  13. @fdansv
  14. @fdansv
  15. @fdansv
Commits on Mar 12, 2014
  1. @fdansv
  2. @fdansv
  3. @fdansv
  4. @fdansv
  5. @fdansv

    comments alert out

    fdansv authored
This page is out of date. Refresh to see the latest.
View
30 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/BoundingBox.java
@@ -1,13 +1,13 @@
package com.mapbox.mapboxsdk.geometry;
-import java.io.Serializable;
-import java.util.ArrayList;
-
+import android.os.Parcel;
+import android.os.Parcelable;
import com.mapbox.mapboxsdk.api.ILatLng;
import com.mapbox.mapboxsdk.views.util.constants.MapViewConstants;
-import android.os.Parcel;
-import android.os.Parcelable;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
/**
* A rectangular geographical area defined in latitude and longitude units.
@@ -89,10 +89,13 @@ public String toString() {
}
public static BoundingBox fromGeoPoints(final ArrayList<? extends LatLng> partialPolyLine) {
- double minLat = Double.MAX_VALUE;
- double minLon = Double.MAX_VALUE;
- double maxLat = Double.MIN_VALUE;
- double maxLon = Double.MIN_VALUE;
+ double minLat = 90;
+ double minLon = 180;
+ double maxLat = -90;
+ double maxLon = -180;
+
+
+
for (final LatLng gp : partialPolyLine) {
final double latitude = gp.getLatitude();
final double longitude = gp.getLongitude();
@@ -126,6 +129,15 @@ public boolean contains(final ILatLng pGeoPoint) {
&& ((longitude < this.mLonEast) && (longitude > this.mLonWest));
}
+ public boolean containsAll(final List<LatLng> list){
+ for(LatLng element: list){
+ if(!this.contains(element)){
+ return false;
+ }
+ }
+ return true;
+ }
+
public static final Parcelable.Creator<BoundingBox> CREATOR = new Parcelable.Creator<BoundingBox>() {
@Override
public BoundingBox createFromParcel(final Parcel in) {
View
31 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/ClusterItem.java
@@ -0,0 +1,31 @@
+package com.mapbox.mapboxsdk.overlay;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.views.MapView;
+
+/**
+ * Created by Francisco Dans on 06/03/14.
+ */
+public class ClusterItem extends Marker{
+ private int childCount = 0;
+
+ public ClusterItem(MapView mv, String aTitle, String aDescription, LatLng aLatLng) {
+ super(mv, aTitle, aDescription, aLatLng);
+ }
+
+ public ClusterItem(String aTitle, String aSnippet, LatLng aLatLng) {
+ super(aTitle, aSnippet, aLatLng);
+ }
+
+ public ClusterItem(MapView view, LatLng result) {
+ super(view, "", "", result);
+ }
+
+ public int getChildCount() {
+ return childCount;
+ }
+
+ public void setChildCount(int childCount) {
+ this.childCount = childCount;
+ }
+}
View
3  MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/Icon.java
@@ -8,6 +8,7 @@
import android.util.Log;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.util.BitmapUtils;
+
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
@@ -86,9 +87,9 @@ protected Bitmap doInBackground(String... src) {
@Override
protected void onPostExecute(Bitmap bitmap) {
drawable = new BitmapDrawable(mResources, bitmap);
- Log.d(TAG, "icon loaded");
if (marker != null) {
marker.setMarker(drawable);
+ Log.w(TAG, "icon loaded");
}
}
}
View
205 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/ItemizedIconOverlay.java
@@ -1,17 +1,25 @@
package com.mapbox.mapboxsdk.overlay;
-import java.util.List;
-
-import com.mapbox.mapboxsdk.DefaultResourceProxyImpl;
-import com.mapbox.mapboxsdk.ResourceProxy;
-import com.mapbox.mapboxsdk.ResourceProxy.bitmap;
-import com.mapbox.mapboxsdk.views.MapView;
import android.content.Context;
import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.drawable.Drawable;
+import android.view.Display;
import android.view.MotionEvent;
+import android.view.WindowManager;
+import com.mapbox.mapboxsdk.DefaultResourceProxyImpl;
+import com.mapbox.mapboxsdk.R;
+import com.mapbox.mapboxsdk.ResourceProxy;
+import com.mapbox.mapboxsdk.ResourceProxy.bitmap;
+import com.mapbox.mapboxsdk.geometry.BoundingBox;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.views.MapView;
import com.mapbox.mapboxsdk.views.util.Projection;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
public class ItemizedIconOverlay<Item extends OverlayItem> extends ItemizedOverlay<Item> {
protected final List<Item> mItemList;
@@ -20,6 +28,11 @@
private final Point mTouchScreenPoint = new Point();
private final Point mItemPoint = new Point();
+ private ItemizedIconOverlay<ClusterItem> clusters;
+ private MapView view;
+ private Context context;
+ private boolean isClusterOverlay;
+
public ItemizedIconOverlay(
final List<Item> pList,
final Drawable pDefaultMarker,
@@ -183,6 +196,178 @@ private boolean activateSelectedItems(final MotionEvent event, final MapView map
return false;
}
+ public void cluster(MapView view, Context context){
+ System.out.println("CLUSTERLIST 1 "+ mItemList);
+ this.view = view;
+ this.context = context;
+ int currentGroup = 0;
+ final double CLUSTERING_THRESHOLD = getThreshold();
+ clusterList = new ArrayList<ClusterItem>();
+ for(OverlayItem item: this.mItemList){
+ item.setClustered(false);
+ item.assignGroup(0);
+ }
+ currentGroup++;
+ for(OverlayItem item: this.mItemList){
+ if (item.getGroup() == 0){
+ item.assignGroup(currentGroup);
+ item.setClustered(true);
+ int counter = 0;
+ for(OverlayItem item2: this.mItemList){
+ if(item2.getGroup() == 0 && PointF.length(screenX(item) - screenX(item2), screenY(item) - screenY(item2)) <= CLUSTERING_THRESHOLD){
+ item2.assignGroup(currentGroup);
+ item2.setClustered(true);
+ counter++;
+ }
+ }
+ if (counter==0) { // If the item has no markers near it there is no sense in clustering it
+ item.setClustered(false);
+ item.assignGroup(0);
+ }
+
+ }
+ currentGroup++;
+ }
+ getGroupSet();
+ view.getOverlays().remove(clusters);
+ if(clusters != null){
+ clusters.removeAllItems();
+ initClusterOverlay();
+ clusters.addItems(clusterList);
+ }
+ else{
+ initClusterOverlay();
+ clusters.addItems(clusterList);
+ }
+
+ view.getOverlays().add(clusters);
+ view.invalidate();
+
+ }
+
+
+ private ArrayList<ClusterItem> clusterList = new ArrayList<ClusterItem>();
+
+
+ private double getThreshold() {
+ WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ Point size = new Point();
+ if (android.os.Build.VERSION.SDK_INT >=13){
+ display.getSize(size);
+ return size.x/10;
+ }
+ else{
+ return display.getWidth();
+ }
+ }
+
+ private HashSet<Integer> getGroupSet(){
+ HashSet<Integer> set = new HashSet<Integer>();
+ for(OverlayItem element: mItemList){
+ if(!set.contains(element.getGroup())){
+ set.add(element.getGroup());
+ generateCenterByGroup((ArrayList<OverlayItem>) mItemList, element.getGroup());
+ }
+ }
+ return set;
+ }
+
+ private LatLng getCenter(ArrayList<OverlayItem> list){
+ int total = list.size();
+
+ double X = 0;
+ double Y = 0;
+ double Z = 0;
+
+ for(OverlayItem i: list){
+ LatLng point = i.getPoint();
+ double lat = point.getLatitude() * Math.PI / 180;
+ double lon = point.getLongitude() * Math.PI / 180;
+
+ double x = Math.cos(lat) * Math.cos(lon);
+ double y = Math.cos(lat) * Math.sin(lon);
+ double z = Math.sin(lat);
+
+ X += x;
+ Y += y;
+ Z += z;
+ }
+
+ X = X / total;
+ Y = Y / total;
+ Z = Z / total;
+
+ double Lon = Math.atan2(Y, X);
+ double Hyp = Math.sqrt(X * X + Y * Y);
+ double Lat = Math.atan2(Z, Hyp);
+
+ return new LatLng(Lat * 180 / Math.PI, Lon * 180 / Math.PI);
+ }
+
+
+
+ private void initClusterOverlay(){
+
+ clusters = new ItemizedIconOverlay<ClusterItem>(clusterList, new ItemizedIconOverlay.OnItemGestureListener<ClusterItem>() {
+ @Override
+ public boolean onItemSingleTapUp(int index, ClusterItem item) {
+ ArrayList<LatLng> activePoints = getCoordinateList(getGroupElements((List<OverlayItem>) mItemList, item.getGroup()));
+ view.zoomToBoundingBox(BoundingBox.fromGeoPoints(activePoints));
+ return false;
+ }
+
+ @Override
+ public boolean onItemLongPress(int index, ClusterItem item) {
+ return false;
+ }
+ }, mResourceProxy);
+ clusters.setCluster(true);
+ }
+
+ private LatLng generateCenterByGroup(ArrayList<OverlayItem> list, int group) {
+ int sumlon = 0, sumlat = 0, count = 0;
+ ArrayList<OverlayItem> tempList = getGroupElements(list, group);
+ LatLng result = getCenter(tempList);
+ ClusterItem m = new ClusterItem(view, result);
+ m.setMarker(context.getResources().getDrawable(R.drawable.clusteri));
+ m.assignGroup(group);
+ m.setMarkerHotspot(OverlayItem.HotspotPlace.CENTER);
+ m.setChildCount(tempList.size());
+ if(m.getChildCount()>1){
+ clusterList.add(m);
+ }
+ return result;
+ }
+
+ private ArrayList<OverlayItem> getGroupElements(List<OverlayItem> list, int group){
+ ArrayList<OverlayItem> tempList = new ArrayList<OverlayItem>();
+ for (OverlayItem element : list) {
+ if (element.getGroup() == group) {
+ tempList.add(element);
+ }
+ }
+ return tempList;
+ }
+
+ private ArrayList<LatLng> getCoordinateList(List<OverlayItem> list){
+ ArrayList<LatLng> theList = new ArrayList<LatLng>();
+ for(OverlayItem element: list){
+ theList.add(element.getPoint());
+ }
+ return theList;
+ }
+
+
+
+ private float screenX(OverlayItem item){
+ return view.getProjection().toPixels(item.getPoint(), null).x;
+ }
+
+ private float screenY(OverlayItem item){
+ return view.getProjection().toPixels(item.getPoint(), null).y;
+ }
+
// ===========================================================
// Getter & Setter
// ===========================================================
@@ -195,6 +380,14 @@ public void setDrawnItemsLimit(final int aLimit) {
this.mDrawnItemsLimit = aLimit;
}
+ public boolean isClusterOverlay() {
+ return isClusterOverlay;
+ }
+
+ public void setCluster(boolean cluster) {
+ this.isClusterOverlay = cluster;
+ }
+
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
View
29 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/ItemizedOverlay.java
@@ -1,20 +1,22 @@
// Created by plusminus on 23:18:23 - 02.10.2008
package com.mapbox.mapboxsdk.overlay;
-import java.util.ArrayList;
-
-import com.mapbox.mapboxsdk.ResourceProxy;
-import com.mapbox.mapboxsdk.views.MapView;
-import com.mapbox.mapboxsdk.overlay.OverlayItem.HotspotPlace;
-import com.mapbox.mapboxsdk.views.safecanvas.ISafeCanvas;
-import com.mapbox.mapboxsdk.views.safecanvas.ISafeCanvas.UnsafeCanvasHandler;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
+import com.mapbox.mapboxsdk.ResourceProxy;
+import com.mapbox.mapboxsdk.overlay.OverlayItem.HotspotPlace;
+import com.mapbox.mapboxsdk.views.MapView;
+import com.mapbox.mapboxsdk.views.safecanvas.ISafeCanvas;
+import com.mapbox.mapboxsdk.views.safecanvas.ISafeCanvas.UnsafeCanvasHandler;
+import com.mapbox.mapboxsdk.views.safecanvas.SafePaint;
import com.mapbox.mapboxsdk.views.util.Projection;
+import java.util.ArrayList;
+
/**
* Draws a list of {@link OverlayItem} as markers to a map. The item with the lowest index is drawn
* as last and therefore the 'topmost' marker. It also gets checked for onTap first. This class is
@@ -99,7 +101,6 @@ protected void drawSafe(ISafeCanvas canvas, MapView mapView, boolean shadow) {
for (int i = size; i >= 0; i--) {
final Item item = getItem(i);
pj.toMapPixels(item.getPoint(), mCurScreenCoords);
-
onDrawItem(canvas, item, mCurScreenCoords, mapView.getMapOrientation());
}
}
@@ -137,6 +138,9 @@ public final Item getItem(final int position) {
* @param aMapOrientation
*/
protected void onDrawItem(final ISafeCanvas canvas, final Item item, final Point curScreenCoords, final float aMapOrientation) {
+ if(item.beingClustered()){
+ return;
+ }
final int state = (mDrawFocusedItem && (mFocusedItem == item) ? OverlayItem.ITEM_STATE_FOCUSED_MASK
: 0);
final Drawable marker = (item.getMarker(state) == null) ? getDefaultMarker(state) : item
@@ -156,6 +160,13 @@ public void onUnsafeCanvas(Canvas canvas) {
}
});
}
+ if(item instanceof ClusterItem){
+ SafePaint paint = new SafePaint();
+ paint.setTextAlign(Paint.Align.CENTER);
+ paint.setTextSize(30);
+ paint.setFakeBoldText(true);
+ canvas.drawText(""+((ClusterItem)item).getChildCount(),curScreenCoords.x, curScreenCoords.y+10, paint);
+ }
}
protected Drawable getDefaultMarker(final int state) {
@@ -230,7 +241,7 @@ public void setDrawFocusedItem(final boolean drawFocusedItem) {
/**
* If the given Item is found in the overlay, force it to be the current focus-bearer. Any
- * registered {@link ItemizedOverlay#OnFocusChangeListener} will be notified. This does not move
+ * registered ItemizedOverlay will be notified. This does not move
* the map, so if the Item isn't already centered, the user may get confused. If the Item is not
* found, this is a no-op. You can also pass null to remove focus.
*/
View
7 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/Marker.java
@@ -1,11 +1,9 @@
package com.mapbox.mapboxsdk.overlay;
import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.tile.TileSystem;
import com.mapbox.mapboxsdk.views.MapView;
/**
@@ -31,8 +29,7 @@ public Marker(MapView mv, String aTitle, String aDescription, LatLng aLatLng) {
if (mv != null) {
context = mv.getContext();
mapView = mv;
- setIcon(new Icon(mv.getResources(), Icon.Size.LARGE, "", "000"));
-// attachTooltip();
+ this.setMarker(context.getResources().getDrawable(R.drawable.defpin));
}
}
View
27 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/overlay/OverlayItem.java
@@ -23,6 +23,32 @@
public static final int ITEM_STATE_SELECTED_MASK = 2;
protected static final Point DEFAULT_MARKER_SIZE = new Point(26, 94);
+ private int group = 0;
+ private boolean clustered;
+
+
+ public int getGroup() {
+ return group;
+ }
+
+ public void assignGroup(int currentGroup) {
+ if (currentGroup==0){
+ this.setClustered(false);
+ }
+ group = currentGroup;
+ }
+
+ public boolean beingClustered() {
+ return clustered;
+ }
+
+ public void setClustered(boolean clustered) {
+ this.clustered = clustered;
+ }
+
+
+
+
/**
* Indicates a hotspot for an area. This is where the origin (0,0) of a point will be located
@@ -109,6 +135,7 @@ public Drawable getMarker(final int stateBitset) {
public void setMarker(final Drawable marker) {
this.mMarker = marker;
+
}
public void setMarkerHotspot(final HotspotPlace place) {
View
9 ...AndroidSDK/src/main/java/com/mapbox/mapboxsdk/tileprovider/modules/MapTileDownloader.java
@@ -2,6 +2,7 @@
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.util.DisplayMetrics;
import com.mapbox.mapboxsdk.tileprovider.MapTile;
@@ -23,8 +24,16 @@
import com.mapbox.mapboxsdk.views.MapView;
import com.mapbox.mapboxsdk.tileprovider.tilesource.TileLayer;
import com.mapbox.mapboxsdk.tileprovider.util.StreamUtils;
+import com.mapbox.mapboxsdk.views.MapView;
+import com.mapbox.mapboxsdk.views.util.TilesLoadedListener;
+import com.squareup.okhttp.HttpResponseCache;
+import com.squareup.okhttp.OkHttpClient;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
import java.util.ArrayList;
+import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
/**
View
89 MapboxAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -1,14 +1,7 @@
package com.mapbox.mapboxsdk.views;
-import android.app.Activity;
-import android.app.AlertDialog;
import android.content.Context;
-import android.content.DialogInterface;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
+import android.graphics.*;
import android.os.Build;
import android.os.Handler;
import android.util.AttributeSet;
@@ -18,41 +11,33 @@
import android.widget.Toast;
import com.mapbox.mapboxsdk.DefaultResourceProxyImpl;
import com.mapbox.mapboxsdk.R;
-import com.mapbox.mapboxsdk.format.GeoJSON;
-import com.mapbox.mapboxsdk.overlay.ItemizedIconOverlay;
-import com.mapbox.mapboxsdk.overlay.ItemizedOverlay;
-import com.mapbox.mapboxsdk.overlay.MapEventsOverlay;
-import com.mapbox.mapboxsdk.overlay.MapEventsReceiver;
-import com.mapbox.mapboxsdk.overlay.Marker;
import com.mapbox.mapboxsdk.ResourceProxy;
import com.mapbox.mapboxsdk.api.ILatLng;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.events.MapListener;
import com.mapbox.mapboxsdk.events.ScrollEvent;
import com.mapbox.mapboxsdk.events.ZoomEvent;
-import com.mapbox.mapboxsdk.overlay.Overlay;
-import com.mapbox.mapboxsdk.overlay.OverlayItem;
-import com.mapbox.mapboxsdk.overlay.OverlayManager;
-import com.mapbox.mapboxsdk.overlay.TilesOverlay;
-import com.mapbox.mapboxsdk.overlay.GeoJSONLayer;
-import com.mapbox.mapboxsdk.tileprovider.MapTileLayerBase;
+import com.mapbox.mapboxsdk.format.GeoJSON;
+import com.mapbox.mapboxsdk.geometry.BoundingBox;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.overlay.*;
+import com.mapbox.mapboxsdk.tile.TileSystem;
import com.mapbox.mapboxsdk.tileprovider.MapTileLayerArray;
+import com.mapbox.mapboxsdk.tileprovider.MapTileLayerBase;
import com.mapbox.mapboxsdk.tileprovider.MapTileLayerBasic;
import com.mapbox.mapboxsdk.tileprovider.modules.MapTileModuleLayerBase;
import com.mapbox.mapboxsdk.tileprovider.tilesource.ITileLayer;
import com.mapbox.mapboxsdk.tileprovider.tilesource.MapboxTileLayer;
import com.mapbox.mapboxsdk.tileprovider.util.SimpleInvalidationHandler;
-import com.mapbox.mapboxsdk.geometry.BoundingBox;
import com.mapbox.mapboxsdk.util.GeometryMath;
import com.mapbox.mapboxsdk.util.NetworkUtils;
import com.mapbox.mapboxsdk.views.util.Projection;
-import com.mapbox.mapboxsdk.views.util.constants.MapViewLayouts;
import com.mapbox.mapboxsdk.views.util.TileLoadedListener;
import com.mapbox.mapboxsdk.views.util.TilesLoadedListener;
import com.mapbox.mapboxsdk.views.util.constants.MapViewConstants;
-import com.mapbox.mapboxsdk.tile.TileSystem;
+import com.mapbox.mapboxsdk.views.util.constants.MapViewLayouts;
import org.json.JSONException;
-import com.mapbox.mapboxsdk.geometry.LatLng;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -144,6 +129,8 @@
private TilesLoadedListener tilesLoadedListener;
TileLoadedListener tileLoadedListener;
+
+
/**
* Constructor for XML layout calls. Should not be used programmatically.
* @param context A copy of the app context
@@ -186,19 +173,20 @@ protected MapView(final Context context, final int tileSizePixels,
String mapId = attrs.getAttributeValue(null, "mapid");
if (mapId != null) {
setTileSource(new MapboxTileLayer(mapId));
- } else {
- AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
- dialog.setTitle(R.string.errorTitle);
- dialog.setMessage(R.string.missingMapIdErrorMessage);
- dialog.setNegativeButton(R.string.closeText, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which)
- {
- ((Activity)getContext()).finish();
- }
- });
- dialog.create().show();
}
+// else {
+// AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
+// dialog.setTitle(R.string.errorTitle);
+// dialog.setMessage(R.string.missingMapIdErrorMessage);
+// dialog.setNegativeButton(R.string.closeText, new DialogInterface.OnClickListener() {
+// @Override
+// public void onClick(DialogInterface dialog, int which)
+// {
+// ((Activity)getContext()).finish();
+// }
+// });
+// dialog.create().show();
+// }
}
public MapView(final Context context, AttributeSet attrs) {
@@ -248,7 +236,6 @@ public Marker addMarker(Marker marker) {
} else {
defaultMarkerOverlay.addItem(marker);
}
- this.invalidate();
marker.addTo(this);
firstMarker = false;
return marker;
@@ -269,6 +256,17 @@ public void addItemizedOverlay(ItemizedOverlay<Marker> itemizedOverlay) {
}
+ public ArrayList<ItemizedIconOverlay> getItemizedOverlays(){
+ ArrayList<ItemizedIconOverlay> list = new ArrayList<ItemizedIconOverlay>();
+ for(Overlay overlay: getOverlays()){
+ System.out.println("ITEMIZED "+overlay);
+ if(overlay instanceof ItemizedOverlay){
+ list.add((ItemizedIconOverlay) overlay);
+ }
+ }
+ return list;
+ }
+
/**
* Load and parse a GeoJSON file at a given URL
* @param URL the URL from which to load the GeoJSON file
@@ -511,6 +509,7 @@ public MapView setZoom(final int aZoomLevel) {
// Allows any views fixed to a Location in the MapView to adjust
this.requestLayout();
+ cluster();
return this;
}
@@ -1128,8 +1127,8 @@ protected void dispatchDraw(final Canvas c) {
// rotate Canvas
c.rotate(mapOrientation,
- mProjection.getScreenRect().exactCenterX(),
- mProjection.getScreenRect().exactCenterY());
+ mProjection.getScreenRect().exactCenterX(),
+ mProjection.getScreenRect().exactCenterY());
// Draw all Overlays.
this.getOverlayManager().onDraw(c, this);
@@ -1177,6 +1176,18 @@ public TileLoadedListener getTileLoadedListener() {
return tileLoadedListener;
}
+ public void cluster() {
+ for(ItemizedIconOverlay overlay: getItemizedOverlays()){
+ if(!overlay.isClusterOverlay()){
+ overlay.cluster(this, context);
+ }
+ }
+ }
+
+ // ===========================================================
+ // Public Classes
+ // ===========================================================
+
/**
* Per-child layout information associated with OpenStreetMapView.
*/
View
BIN  MapboxAndroidSDK/src/main/res/drawable/clusteri.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  MapboxAndroidSDK/src/main/res/drawable/defpin.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Something went wrong with that request. Please try again.