From a0d1b177d71dd081eb0f89c397b676d6d349d6fa Mon Sep 17 00:00:00 2001 From: mar-v-in Date: Mon, 16 Jun 2014 13:16:08 +0200 Subject: [PATCH] Marker supprt (without info window) --- AndroidManifest.xml | 2 +- res/drawable-xhdpi/maps_default_marker.png | Bin 0 -> 4303 bytes .../gms/common/safeparcel/SafeReader.java | 11 ++ .../internal/CameraUpdateFactoryImpl.java | 12 +- .../gms/maps/internal/GoogleMapImpl.java | 42 ++++- .../maps/internal/IOnMarkerClickListener.aidl | 3 + .../gms/maps/model/BitmapDescriptor.java | 41 +++++ .../google/android/gms/maps/model/LatLng.java | 5 + .../android/gms/maps/model/LatLngBounds.java | 4 +- .../android/gms/maps/model/MarkerOptions.java | 125 ++++++++++++++ .../internal/AbstractBitmapDescriptor.java | 40 +++++ .../model/internal/AssetBitmapDescriptor.java | 21 ++- .../internal/BitmapBitmapDescriptor.java | 11 +- .../gms/maps/model/internal/CircleImpl.java | 2 +- .../internal/DefaultBitmapDescriptor.java | 29 +++- .../model/internal/FileBitmapDescriptor.java | 16 +- .../model/internal/GroundOverlayImpl.java | 2 +- .../maps/model/internal/IMarkerDelegate.aidl | 4 +- .../gms/maps/model/internal/MarkerImpl.java | 161 +++++++++++++++--- .../gms/maps/model/internal/PolygonImpl.java | 2 +- .../gms/maps/model/internal/PolylineImpl.java | 2 +- .../internal/ResourceBitmapDescriptor.java | 23 ++- 22 files changed, 505 insertions(+), 53 deletions(-) create mode 100644 res/drawable-xhdpi/maps_default_marker.png create mode 100644 src/com/google/android/gms/maps/model/internal/AbstractBitmapDescriptor.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 2ff2ec5a..b8e53e8a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,7 +17,7 @@ + android:versionCode="4452036"> diff --git a/res/drawable-xhdpi/maps_default_marker.png b/res/drawable-xhdpi/maps_default_marker.png new file mode 100644 index 0000000000000000000000000000000000000000..a963793a86bb1efbb0c7fa0bda086ae63a2e055b GIT binary patch literal 4303 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 literal 0 HcmV?d00001 diff --git a/src/com/google/android/gms/common/safeparcel/SafeReader.java b/src/com/google/android/gms/common/safeparcel/SafeReader.java index 5f46fa03..6dd73983 100644 --- a/src/com/google/android/gms/common/safeparcel/SafeReader.java +++ b/src/com/google/android/gms/common/safeparcel/SafeReader.java @@ -87,6 +87,17 @@ public class SafeReader { readStart(parcel, position, 8); return parcel.readDouble(); } + + public static String readString(Parcel parcel, int position) { + int length = readStart(parcel, position); + int start = parcel.dataPosition(); + if (length == 0) + return null; + String string = parcel.readString(); + parcel.setDataPosition(start + length); + return string; + } + public static IBinder readBinder(Parcel parcel, int position) { int length = readStart(parcel, position); int start = parcel.dataPosition(); diff --git a/src/com/google/android/gms/maps/internal/CameraUpdateFactoryImpl.java b/src/com/google/android/gms/maps/internal/CameraUpdateFactoryImpl.java index b6b4f60d..83a9e80d 100644 --- a/src/com/google/android/gms/maps/internal/CameraUpdateFactoryImpl.java +++ b/src/com/google/android/gms/maps/internal/CameraUpdateFactoryImpl.java @@ -130,10 +130,14 @@ public class CameraUpdateFactoryImpl extends ICameraUpdateFactoryDelegate.Stub { return new ObjectWrapper(new CameraUpdate() { @Override public void update(GoogleMapImpl map) { - // TODO - } - }); - } + double latSpan = bounds.northEast.latitude - bounds.southWest.latitude, + lonSpan = bounds.northEast.longitude - bounds.southWest.longitude; + map.getController().zoomToSpan((int) (latSpan * 1E6), (int) (lonSpan * 1E6)); + map.getController().setCenter(new GeoPoint((int) ((bounds.southWest.latitude + latSpan/2) * 1E6), + (int) ((bounds.southWest.longitude + lonSpan/2) * 1E6))); + } + }); + } @Override public IObjectWrapper newLatLngBoundsWithSize(LatLngBounds bounds, int i1, int i2, int i3) throws RemoteException { diff --git a/src/com/google/android/gms/maps/internal/GoogleMapImpl.java b/src/com/google/android/gms/maps/internal/GoogleMapImpl.java index af154577..a768245b 100644 --- a/src/com/google/android/gms/maps/internal/GoogleMapImpl.java +++ b/src/com/google/android/gms/maps/internal/GoogleMapImpl.java @@ -47,11 +47,14 @@ public class GoogleMapImpl { private final Delegate delegate = new Delegate(); private MapView mapView; private int mapType = 1; + private Context context; + private IOnMarkerClickListener markerClickListener; public GoogleMapImpl(LayoutInflater inflater, GoogleMapOptions options) { - this.view = new FrameLayout(inflater.getContext()); + context = inflater.getContext(); + this.view = new FrameLayout(context); try { - mapView = (MapView) Class.forName("com.google.android.maps.MapView").getConstructor(Context.class, String.class).newInstance(inflater.getContext(), null); + mapView = (MapView) Class.forName("com.google.android.maps.MapView").getConstructor(Context.class, String.class).newInstance(context, null); view.addView(mapView); } catch (Exception e) { Log.d(TAG, "Sorry, can't create legacy MapView"); @@ -63,7 +66,15 @@ public class GoogleMapImpl { } - MapView getMapView() { + public IOnMarkerClickListener getMarkerClickListener() { + return markerClickListener; + } + + public Context getContext() { + return context; + } + + MapView getMapView() { return mapView; } @@ -79,7 +90,20 @@ public class GoogleMapImpl { return delegate; } - private class Delegate extends IGoogleMapDelegate.Stub { + public void remove(MarkerImpl marker) { + mapView.getOverlays().remove(marker); + } + + public void redraw() { + mapView.postInvalidate(); + try { + ((MapView.WrappedMapView) mapView.getWrapped()).postInvalidate(); + } catch (Exception e) { + Log.w(TAG, "MapView does not support extended microg features", e); + } + } + + private class Delegate extends IGoogleMapDelegate.Stub { @Override public CameraPosition getCameraPosition() throws RemoteException { if (mapView == null) return null; @@ -136,7 +160,10 @@ public class GoogleMapImpl { @Override public IMarkerDelegate addMarker(MarkerOptions options) throws RemoteException { - return new MarkerImpl(options); + MarkerImpl marker = new MarkerImpl(options, GoogleMapImpl.this); + mapView.getOverlays().add(marker.getOverlay()); + redraw(); + return marker; } @Override @@ -151,7 +178,8 @@ public class GoogleMapImpl { @Override public void clear() throws RemoteException { - + mapView.getOverlays().clear(); + redraw(); } @Override @@ -256,7 +284,7 @@ public class GoogleMapImpl { @Override public void setOnMarkerClickListener(IOnMarkerClickListener listener) throws RemoteException { - + markerClickListener = listener; } @Override diff --git a/src/com/google/android/gms/maps/internal/IOnMarkerClickListener.aidl b/src/com/google/android/gms/maps/internal/IOnMarkerClickListener.aidl index d469aa2f..d77a0bec 100644 --- a/src/com/google/android/gms/maps/internal/IOnMarkerClickListener.aidl +++ b/src/com/google/android/gms/maps/internal/IOnMarkerClickListener.aidl @@ -1,4 +1,7 @@ package com.google.android.gms.maps.internal; +import com.google.android.gms.maps.model.internal.IMarkerDelegate; + interface IOnMarkerClickListener { + boolean onMarkerClick(IMarkerDelegate marker); } diff --git a/src/com/google/android/gms/maps/model/BitmapDescriptor.java b/src/com/google/android/gms/maps/model/BitmapDescriptor.java index af5005e6..fe8ef0ee 100644 --- a/src/com/google/android/gms/maps/model/BitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/BitmapDescriptor.java @@ -16,7 +16,11 @@ package com.google.android.gms.maps.model; +import android.content.Context; +import android.graphics.Bitmap; import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.dynamic.ObjectWrapper; +import com.google.android.gms.maps.model.internal.AbstractBitmapDescriptor; public class BitmapDescriptor { private final IObjectWrapper remoteObject; @@ -28,4 +32,41 @@ public class BitmapDescriptor { public IObjectWrapper getRemoteObject() { return remoteObject; } + + public AbstractBitmapDescriptor getDescriptor() { + if (remoteObject == null) return null; + Object unwrap = ObjectWrapper.unwrap(remoteObject); + if (unwrap instanceof AbstractBitmapDescriptor) { + return ((AbstractBitmapDescriptor) unwrap); + } else { + return null; + } + } + + public Bitmap getBitmap() { + if (getDescriptor() != null) { + return getDescriptor().getBitmap(); + } + return null; + } + + @Override + public String toString() { + return "BitmapDescriptor{" + + "remote=" + getDescriptor() + + '}'; + } + + public void loadBitmapAsync(final Context context, final Runnable after) { + if (getDescriptor() != null) { + new Thread(new Runnable() { + @Override + public void run() { + if (getDescriptor().loadBitmap(context) != null) { + after.run(); + } + } + }).start(); + } + } } diff --git a/src/com/google/android/gms/maps/model/LatLng.java b/src/com/google/android/gms/maps/model/LatLng.java index cca995eb..d1af36da 100644 --- a/src/com/google/android/gms/maps/model/LatLng.java +++ b/src/com/google/android/gms/maps/model/LatLng.java @@ -20,6 +20,7 @@ import android.os.Parcel; import com.google.android.gms.common.safeparcel.SafeParcelable; import com.google.android.gms.common.safeparcel.SafeReader; import com.google.android.gms.common.safeparcel.SafeWriter; +import com.google.android.maps.GeoPoint; public class LatLng implements SafeParcelable { public static Creator CREATOR = new Creator() { @@ -98,4 +99,8 @@ public class LatLng implements SafeParcelable { SafeWriter.write(dest, 3, longitude); SafeWriter.writeEnd(dest, start); } + + public GeoPoint toGeoPoint() { + return new GeoPoint((int) (latitude * 1E6F), (int) (longitude * 1E6F)); + } } diff --git a/src/com/google/android/gms/maps/model/LatLngBounds.java b/src/com/google/android/gms/maps/model/LatLngBounds.java index 501799cd..94d47fc0 100644 --- a/src/com/google/android/gms/maps/model/LatLngBounds.java +++ b/src/com/google/android/gms/maps/model/LatLngBounds.java @@ -32,8 +32,8 @@ public class LatLngBounds implements SafeParcelable { } }; private int versionCode; - private LatLng southWest; - private LatLng northEast; + public LatLng southWest; + public LatLng northEast; public LatLngBounds() { } diff --git a/src/com/google/android/gms/maps/model/MarkerOptions.java b/src/com/google/android/gms/maps/model/MarkerOptions.java index df103158..e47bc3c8 100644 --- a/src/com/google/android/gms/maps/model/MarkerOptions.java +++ b/src/com/google/android/gms/maps/model/MarkerOptions.java @@ -16,11 +16,29 @@ package com.google.android.gms.maps.model; +import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; +import com.google.android.gms.common.safeparcel.SafeReader; +import com.google.android.gms.dynamic.ObjectWrapper; public class MarkerOptions implements Parcelable { + private int versionCode = 1; + private LatLng position; + private String title; + private String snippet; + private BitmapDescriptor icon; + private float anchorU = 0.5F; + private float anchorV = 1F; + private boolean draggable; + private boolean visible; + private boolean flat; + private float rotation = 0F; + private float infoWindowAnchorU = 0F; + private float infoWindowAnchorV = 1F; + private float alpha = 1F; + @Override public int describeContents() { return 0; @@ -34,6 +52,113 @@ public class MarkerOptions implements Parcelable { } private MarkerOptions(Parcel in) { + int end = SafeReader.readStart(in); + while (in.dataPosition() < end) { + int position = SafeReader.readSingleInt(in); + switch (SafeReader.halfOf(position)) { + case 1: + this.versionCode = SafeReader.readInt(in, position); + break; + case 2: + this.position = SafeReader.readParcelable(in, position, LatLng.CREATOR); + break; + case 3: + this.title = SafeReader.readString(in, position); + break; + case 4: + this.snippet = SafeReader.readString(in, position); + break; + case 5: + IBinder icon = SafeReader.readBinder(in, position); + this.icon = icon == null ? null : new BitmapDescriptor(ObjectWrapper.asInterface(icon)); + break; + case 6: + this.anchorU = SafeReader.readFloat(in, position); + break; + case 7: + this.anchorV = SafeReader.readFloat(in, position); + break; + case 8: + this.draggable = SafeReader.readBool(in, position); + break; + case 9: + this.visible = SafeReader.readBool(in, position); + break; + case 10: + this.flat = SafeReader.readBool(in, position); + break; + case 11: + this.rotation = SafeReader.readFloat(in, position); + break; + case 12: + this.infoWindowAnchorU = SafeReader.readFloat(in, position); + break; + case 13: + this.infoWindowAnchorV = SafeReader.readFloat(in, position); + break; + case 14: + this.rotation = SafeReader.readFloat(in, position); + break; + default: + SafeReader.skip(in, position); + break; + } + } + if (in.dataPosition() > end) { + throw new SafeReader.ReadException("Overread allowed size end=" + end, in); + } + } + + public LatLng getPosition() { + return position; + } + + public String getTitle() { + return title; + } + + public String getSnippet() { + return snippet; + } + + public BitmapDescriptor getIcon() { + return icon; + } + + public float getAnchorU() { + return anchorU; + } + + public float getAnchorV() { + return anchorV; + } + + public boolean isDraggable() { + return draggable; + } + + public boolean isVisible() { + return visible; + } + + public boolean isFlat() { + return flat; + } + + public float getRotation() { + return rotation; + } + + public float getInfoWindowAnchorU() { + return infoWindowAnchorU; + } + + public float getInfoWindowAnchorV() { + return infoWindowAnchorV; + } + + public float getAlpha() { + return alpha; } public static Creator CREATOR = new Creator() { diff --git a/src/com/google/android/gms/maps/model/internal/AbstractBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/AbstractBitmapDescriptor.java new file mode 100644 index 00000000..6ef7927b --- /dev/null +++ b/src/com/google/android/gms/maps/model/internal/AbstractBitmapDescriptor.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2014 μg Project Team + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.gms.maps.model.internal; + +import android.content.Context; +import android.graphics.Bitmap; + +public abstract class AbstractBitmapDescriptor { + + private Bitmap bitmap; + + protected abstract Bitmap generateBitmap(Context context); + + public Bitmap loadBitmap(Context context) { + if (bitmap == null) { + synchronized (this) { + if (bitmap == null) bitmap = generateBitmap(context); + } + } + return bitmap; + } + + public Bitmap getBitmap() { + return bitmap; + } +} diff --git a/src/com/google/android/gms/maps/model/internal/AssetBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/AssetBitmapDescriptor.java index e20d13fb..eb039055 100644 --- a/src/com/google/android/gms/maps/model/internal/AssetBitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/internal/AssetBitmapDescriptor.java @@ -16,7 +16,26 @@ package com.google.android.gms.maps.model.internal; -public class AssetBitmapDescriptor { +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import java.io.IOException; + +public class AssetBitmapDescriptor extends AbstractBitmapDescriptor { + private String assetName; + public AssetBitmapDescriptor(String assetName) { + this.assetName = assetName; } + + @Override + protected Bitmap generateBitmap(Context context) { + try { + return BitmapFactory.decodeStream(context.getAssets().open(assetName)); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } } diff --git a/src/com/google/android/gms/maps/model/internal/BitmapBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/BitmapBitmapDescriptor.java index 62bedb92..3c0b370d 100644 --- a/src/com/google/android/gms/maps/model/internal/BitmapBitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/internal/BitmapBitmapDescriptor.java @@ -16,9 +16,18 @@ package com.google.android.gms.maps.model.internal; +import android.content.Context; import android.graphics.Bitmap; -public class BitmapBitmapDescriptor { +public class BitmapBitmapDescriptor extends AbstractBitmapDescriptor { + private Bitmap bitmap; + public BitmapBitmapDescriptor(Bitmap bitmap) { + this.bitmap = bitmap; + } + + @Override + public Bitmap generateBitmap(Context context) { + return bitmap; } } diff --git a/src/com/google/android/gms/maps/model/internal/CircleImpl.java b/src/com/google/android/gms/maps/model/internal/CircleImpl.java index 103e7723..e0ae0881 100644 --- a/src/com/google/android/gms/maps/model/internal/CircleImpl.java +++ b/src/com/google/android/gms/maps/model/internal/CircleImpl.java @@ -116,7 +116,7 @@ public class CircleImpl extends ICircleDelegate.Stub { @Override public boolean equalsRemote(ICircleDelegate other) throws RemoteException { - return other.getId().equals(getId()); + return other != null &&other.getId().equals(getId()); } @Override diff --git a/src/com/google/android/gms/maps/model/internal/DefaultBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/DefaultBitmapDescriptor.java index c80610ee..1efea912 100644 --- a/src/com/google/android/gms/maps/model/internal/DefaultBitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/internal/DefaultBitmapDescriptor.java @@ -16,8 +16,33 @@ package com.google.android.gms.maps.model.internal; -public class DefaultBitmapDescriptor { - public DefaultBitmapDescriptor(float hue) { +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Color; +import com.google.android.gms.R; +import com.google.android.gms.maps.internal.ResourcesContainer; +public class DefaultBitmapDescriptor extends AbstractBitmapDescriptor { + private float hue; + + public DefaultBitmapDescriptor(float hue) { + this.hue = hue; + } + + @Override + public Bitmap generateBitmap(Context context) { + Bitmap source = BitmapFactory.decodeResource(ResourcesContainer.get(), R.drawable.maps_default_marker); + Bitmap bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig()); + float[] hsv = new float[3]; + for (int x = 0; x < bitmap.getWidth(); x++) { + for (int y = 0; y < bitmap.getHeight(); y++) { + int pixel = source.getPixel(x, y); + Color.colorToHSV(pixel, hsv); + hsv[0] = (hsv[0] + hue) % 360; + bitmap.setPixel(x, y, Color.HSVToColor(Color.alpha(pixel), hsv)); + } + } + return bitmap; } } diff --git a/src/com/google/android/gms/maps/model/internal/FileBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/FileBitmapDescriptor.java index 6e4ceacc..c225fc9a 100644 --- a/src/com/google/android/gms/maps/model/internal/FileBitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/internal/FileBitmapDescriptor.java @@ -16,7 +16,19 @@ package com.google.android.gms.maps.model.internal; -public class FileBitmapDescriptor { +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +public class FileBitmapDescriptor extends AbstractBitmapDescriptor { + private String fileName; + public FileBitmapDescriptor(String fileName) { - } + this.fileName = fileName; + } + + @Override + public Bitmap generateBitmap(Context context) { + return BitmapFactory.decodeFile(fileName); + } } diff --git a/src/com/google/android/gms/maps/model/internal/GroundOverlayImpl.java b/src/com/google/android/gms/maps/model/internal/GroundOverlayImpl.java index 70dde6ce..6ce8eb59 100644 --- a/src/com/google/android/gms/maps/model/internal/GroundOverlayImpl.java +++ b/src/com/google/android/gms/maps/model/internal/GroundOverlayImpl.java @@ -129,7 +129,7 @@ public class GroundOverlayImpl extends IGroundOverlayDelegate.Stub { @Override public boolean equalsRemote(IGroundOverlayDelegate other) throws RemoteException { - return other.getId().equals(getId()); + return other != null && other.getId().equals(getId()); } @Override diff --git a/src/com/google/android/gms/maps/model/internal/IMarkerDelegate.aidl b/src/com/google/android/gms/maps/model/internal/IMarkerDelegate.aidl index aa1173c3..d4eccf6d 100644 --- a/src/com/google/android/gms/maps/model/internal/IMarkerDelegate.aidl +++ b/src/com/google/android/gms/maps/model/internal/IMarkerDelegate.aidl @@ -10,7 +10,7 @@ interface IMarkerDelegate { LatLng getPosition(); void setTitle(String title); String getTitle(); - void setSnippet(String title); + void setSnippet(String snippet); String getSnippet(); void setDraggable(boolean drag); boolean isDraggable(); @@ -21,7 +21,7 @@ interface IMarkerDelegate { boolean isVisible(); boolean equalsRemote(IMarkerDelegate other); int hashCodeRemote(); - void todo(IObjectWrapper obj); + void setIcon(IObjectWrapper obj); void setAnchor(float x, float y); void setFlat(boolean flat); boolean isFlat(); diff --git a/src/com/google/android/gms/maps/model/internal/MarkerImpl.java b/src/com/google/android/gms/maps/model/internal/MarkerImpl.java index f44e0a76..de2692e3 100644 --- a/src/com/google/android/gms/maps/model/internal/MarkerImpl.java +++ b/src/com/google/android/gms/maps/model/internal/MarkerImpl.java @@ -16,63 +16,165 @@ package com.google.android.gms.maps.model.internal; +import android.graphics.*; +import android.graphics.drawable.Drawable; import android.os.RemoteException; +import android.util.Log; +import android.view.MotionEvent; import com.google.android.gms.dynamic.IObjectWrapper; +import com.google.android.gms.dynamic.ObjectWrapper; +import com.google.android.gms.maps.internal.GoogleMapImpl; +import com.google.android.gms.maps.internal.IOnMarkerClickListener; +import com.google.android.gms.maps.model.BitmapDescriptor; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.maps.GeoPoint; +import com.google.android.maps.MapView; +import com.google.android.maps.Overlay; public class MarkerImpl extends IMarkerDelegate.Stub { - public MarkerImpl(MarkerOptions options) { + private static final String TAG = MarkerImpl.class.getName(); + + private float alpha; + private boolean flat; + private boolean draggable; + private String id = Integer.toHexString(hashCode()); + private LatLng position; + private float anchorU; + private float anchorV; + private float rotation; + private String snippet; + private String title; + private boolean visible; + + private BitmapDescriptor icon; + + private GoogleMapImpl map; + private Overlay overlay = new Overlay() { + private Point point = new Point(); + + @Override + public boolean onTap(GeoPoint p, MapView mapView) { + Point touchPoint = mapView.getProjection().toPixels(p, null); + Bitmap bitmap = icon.getBitmap(); + if (bitmap == null) return false; + mapView.getProjection().toPixels(position.toGeoPoint(), point); + float xTest = bitmap.getWidth() * anchorU + touchPoint.x - point.x; + float yTest = bitmap.getHeight() * anchorV + touchPoint.y - point.y; + if (0 < xTest && xTest < bitmap.getWidth() && 0 < yTest && yTest < bitmap.getHeight()) { + Log.d(TAG, "touched " + title); + IOnMarkerClickListener markerClickListener = map.getMarkerClickListener(); + boolean result = false; + if (markerClickListener != null) { + try { + result = markerClickListener.onMarkerClick(MarkerImpl.this); + } catch (RemoteException e) { + Log.w(TAG, e); + } + } + if (!result) { + mapView.getController().animateTo(position.toGeoPoint()); + // TODO info window + } + return true; + } + return false; + } + + @Override + public void draw(Canvas canvas, MapView mapView, boolean shadow) { + if (!shadow) { + Bitmap bitmap = icon.getBitmap(); + if (bitmap != null) { + mapView.getProjection().toPixels(position.toGeoPoint(), point); + float x = point.x - bitmap.getWidth() * anchorU; + float y = point.y - bitmap.getHeight() * anchorV; + Paint paint = new Paint(); + paint.setAlpha((int) (alpha * 255)); + Matrix matrix = new Matrix(); + matrix.setRotate(rotation, bitmap.getWidth() / 2, bitmap.getHeight() / 2); + matrix.postTranslate(x, y); + canvas.drawBitmap(bitmap, matrix, paint); + } else { + icon.loadBitmapAsync(map.getContext(), new Runnable() { + @Override + public void run() { + map.redraw(); + } + }); + } + } else { + // TODO: shadow based on flat + } + } + }; + + public MarkerImpl(MarkerOptions options, GoogleMapImpl map) { + this.map = map; + this.alpha = options.getAlpha(); + this.draggable = options.isDraggable(); + this.position = options.getPosition(); + if (position == null) position = new LatLng(0, 0); + this.rotation = options.getRotation(); + this.anchorU = options.getAnchorU(); + this.anchorV = options.getAnchorV(); + this.snippet = options.getSnippet(); + this.title = options.getTitle(); + this.visible = options.isVisible(); + this.icon = options.getIcon(); + if (icon == null) + icon = new BitmapDescriptor(new ObjectWrapper(new DefaultBitmapDescriptor(0))); + Log.d(TAG, "New: " + title + " @ " + position + ", " + icon); } @Override public void remove() throws RemoteException { - + map.remove(this); } @Override public String getId() throws RemoteException { - return null; + return id; } @Override public void setPosition(LatLng pos) throws RemoteException { - + this.position = pos; } @Override public LatLng getPosition() throws RemoteException { - return null; + return position; } @Override public void setTitle(String title) throws RemoteException { - + this.title = title; } @Override public String getTitle() throws RemoteException { - return null; + return title; } @Override - public void setSnippet(String title) throws RemoteException { - + public void setSnippet(String snippet) throws RemoteException { + this.snippet = snippet; } @Override public String getSnippet() throws RemoteException { - return null; + return snippet; } @Override public void setDraggable(boolean drag) throws RemoteException { - + this.draggable = drag; } @Override public boolean isDraggable() throws RemoteException { - return false; + return draggable; } @Override @@ -92,37 +194,42 @@ public class MarkerImpl extends IMarkerDelegate.Stub { @Override public void setVisible(boolean visible) throws RemoteException { - + this.visible = visible; } @Override public boolean isVisible() throws RemoteException { - return false; + return visible; } @Override public boolean equalsRemote(IMarkerDelegate other) throws RemoteException { - return false; + return other != null && other.getId().equals(getId()); } @Override public int hashCodeRemote() throws RemoteException { - return 0; + return hashCode(); } @Override - public void todo(IObjectWrapper obj) throws RemoteException { - + public void setIcon(IObjectWrapper obj) throws RemoteException { + icon = new BitmapDescriptor(obj); + if (icon == null) + icon = new BitmapDescriptor(new ObjectWrapper(new DefaultBitmapDescriptor(0))); + map.redraw(); } @Override public void setAnchor(float x, float y) throws RemoteException { - + anchorU = x; + anchorV = y; + map.redraw(); } @Override public void setFlat(boolean flat) throws RemoteException { - + map.redraw(); } @Override @@ -132,12 +239,13 @@ public class MarkerImpl extends IMarkerDelegate.Stub { @Override public void setRotation(float rotation) throws RemoteException { - + this.rotation = rotation; + map.redraw(); } @Override public float getRotation() throws RemoteException { - return 0; + return rotation; } @Override @@ -147,11 +255,16 @@ public class MarkerImpl extends IMarkerDelegate.Stub { @Override public void setAlpha(float alpha) throws RemoteException { - + this.alpha = alpha; + map.redraw(); } @Override public float getAlpha() throws RemoteException { - return 0; + return alpha; + } + + public Overlay getOverlay() { + return overlay; } } diff --git a/src/com/google/android/gms/maps/model/internal/PolygonImpl.java b/src/com/google/android/gms/maps/model/internal/PolygonImpl.java index 4791ae84..6082d759 100644 --- a/src/com/google/android/gms/maps/model/internal/PolygonImpl.java +++ b/src/com/google/android/gms/maps/model/internal/PolygonImpl.java @@ -129,7 +129,7 @@ public class PolygonImpl extends IPolygonDelegate.Stub { @Override public boolean equalsRemote(IPolygonDelegate other) throws RemoteException { - return other.getId().equals(getId()); + return other != null && other.getId().equals(getId()); } @Override diff --git a/src/com/google/android/gms/maps/model/internal/PolylineImpl.java b/src/com/google/android/gms/maps/model/internal/PolylineImpl.java index 3ed9ad64..310029bd 100644 --- a/src/com/google/android/gms/maps/model/internal/PolylineImpl.java +++ b/src/com/google/android/gms/maps/model/internal/PolylineImpl.java @@ -111,7 +111,7 @@ public class PolylineImpl extends IPolylineDelegate.Stub { @Override public boolean equalsRemote(IPolylineDelegate other) throws RemoteException { - return other.getId().equals(getId()); + return other != null && other.getId().equals(getId()); } @Override diff --git a/src/com/google/android/gms/maps/model/internal/ResourceBitmapDescriptor.java b/src/com/google/android/gms/maps/model/internal/ResourceBitmapDescriptor.java index 70057a46..625209c6 100644 --- a/src/com/google/android/gms/maps/model/internal/ResourceBitmapDescriptor.java +++ b/src/com/google/android/gms/maps/model/internal/ResourceBitmapDescriptor.java @@ -16,8 +16,25 @@ package com.google.android.gms.maps.model.internal; -public class ResourceBitmapDescriptor { - public ResourceBitmapDescriptor(int resourceId) { +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.util.Log; +import com.google.android.gms.maps.internal.ResourcesContainer; - } +public class ResourceBitmapDescriptor extends AbstractBitmapDescriptor { + private static final String TAG = ResourceBitmapDescriptor.class.getName(); + + private int resourceId; + + public ResourceBitmapDescriptor(int resourceId) { + this.resourceId = resourceId; + } + + @Override + public Bitmap generateBitmap(Context context) { + return BitmapFactory.decodeResource(context.getResources(), resourceId); + } }