diff --git a/LICENSE b/LICENSE index f52ddb7f..7e16a172 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2013 Appcelerator, Inc. +Copyright 2013-present Appcelerator, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/android/src/ti/map/MapModule.java b/android/src/ti/map/MapModule.java index ff21d374..53f8c421 100644 --- a/android/src/ti/map/MapModule.java +++ b/android/src/ti/map/MapModule.java @@ -8,21 +8,33 @@ */ package ti.map; +import android.location.Location; import androidx.annotation.NonNull; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.OnMapsSdkInitializedCallback; import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.LatLng; +import com.google.maps.android.PolyUtil; + import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.annotations.Kroll; +import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.common.Log; import org.appcelerator.titanium.TiApplication; +import org.appcelerator.titanium.util.TiConvert; +import org.appcelerator.titanium.TiC; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; @Kroll.module(name = "Map", id = "ti.map") public class MapModule extends KrollModule implements OnMapsSdkInitializedCallback { public static final String EVENT_MAP_CLICK = "mapclick"; + public static final String EVENT_POI_CLICK = "poiclick"; public static final String EVENT_PIN_CHANGE_DRAG_STATE = "pinchangedragstate"; public static final String EVENT_ON_SNAPSHOT_READY = "onsnapshotready"; public static final String EVENT_REGION_WILL_CHANGE = "regionwillchange"; @@ -70,6 +82,7 @@ public class MapModule extends KrollModule implements OnMapsSdkInitializedCallba public static final String PROPERTY_CENTER = "center"; public static final String PROPERTY_RADIUS = "radius"; public static final String PROPERTY_INDOOR_ENABLED = "indoorEnabled"; + public static final String PROPERTY_PLACE_ID = "placeID"; public static final String PROPERTY_DESELECTED = "deselected"; public static final String PROPERTY_LITE_MODE = "liteMode"; public static final String PROPERTY_MIN_CLUSTER_SIZE = "minClusterSize"; @@ -159,6 +172,35 @@ public int isGooglePlayServicesAvailable() return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(TiApplication.getInstance()); } + @Kroll.method + public boolean geometryContainsLocation(KrollDict dict) + { + HashMap point = (HashMap) dict.get("location"); + LatLng location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)),TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE))); + List polygon = new ArrayList<>(); + Object[] dictPoints =(Object[]) dict.get("points"); + for (Object _point : dictPoints) { + HashMap _location = (HashMap)_point; + polygon.add(new LatLng(TiConvert.toDouble(_location.get(TiC.PROPERTY_LATITUDE)), TiConvert.toDouble(_location.get(TiC.PROPERTY_LONGITUDE)))); + } + return PolyUtil.containsLocation(location, polygon, true); + } + + @Kroll.method + public double geometryDistanceBetweenPoints(Object jsLocation1, Object jsLocation2) + { + HashMap location1Dict = (HashMap) jsLocation1; + HashMap location2Dict = (HashMap) jsLocation2; + + LatLng location1 = new LatLng(TiConvert.toDouble(location1Dict.get(TiC.PROPERTY_LATITUDE)), TiConvert.toDouble(location1Dict.get(TiC.PROPERTY_LONGITUDE))); + LatLng location2 = new LatLng(TiConvert.toDouble(location2Dict.get(TiC.PROPERTY_LATITUDE)), TiConvert.toDouble(location2Dict.get(TiC.PROPERTY_LONGITUDE))); + + float[] results = new float[1]; + Location.distanceBetween(location1.latitude, location1.longitude, location2.latitude, location2.longitude, results); + + return results[0]; + } + @Override public String getApiName() { diff --git a/android/src/ti/map/PolygonProxy.java b/android/src/ti/map/PolygonProxy.java index 45df62c4..f4029e6a 100644 --- a/android/src/ti/map/PolygonProxy.java +++ b/android/src/ti/map/PolygonProxy.java @@ -151,26 +151,41 @@ public void addLocation(Object loc, ArrayList locationArray, boolean lis } } - public ArrayList processPoints(Object points, boolean list) + public List processPoints(Object points, boolean list) { - ArrayList locationArray = new ArrayList(); // encoded (result from routing API) if (points instanceof String) { List locationList = PolyUtil.decode((String) points); return new ArrayList(locationList); - } - // multiple points - if (points instanceof Object[]) { + // Handle an array of points + } else if (points instanceof Object[]) { + Object[] pointsArray = (Object[]) points; + for (int i = 0; i < pointsArray.length; i++) { + Object obj = pointsArray[i]; + addLocation(obj, locationArray, list); + } + + return locationArray; + // Handle encoded polyline + } else if (points instanceof Object[]) { Object[] pointsArray = (Object[]) points; for (int i = 0; i < pointsArray.length; i++) { Object obj = pointsArray[i]; addLocation(obj, locationArray, list); } + + return locationArray; + // Handle encoded polyline + } else if (points instanceof String) { + for (LatLng point : PolyUtil.decode((String) points)) { + addLocation(point, locationArray, list); + } + return locationArray; } - // single point + // Single point addLocation(points, locationArray, list); return locationArray; } diff --git a/android/src/ti/map/PolylineProxy.java b/android/src/ti/map/PolylineProxy.java index 097fd3c3..2b217aa3 100644 --- a/android/src/ti/map/PolylineProxy.java +++ b/android/src/ti/map/PolylineProxy.java @@ -34,10 +34,9 @@ propertyAccessors = { MapModule.PROPERTY_STROKE_COLOR, MapModule.PROPERTY_STROKE_WIDTH, PolylineProxy.PROPERTY_STROKE_COLOR2, PolylineProxy.PROPERTY_STROKE_WIDTH2, PolylineProxy.PROPERTY_STROKE_PATTERN2, PolylineProxy.PROPERTY_ZINDEX, - MapModule.PROPERTY_POINTS, TiC.PROPERTY_TOUCH_ENABLED }) + MapModule.PROPERTY_POINTS, TiC.PROPERTY_TOUCH_ENABLED, PolylineProxy.PROPERTY_GEODESIC }) public class PolylineProxy extends KrollProxy implements IShape { - private PolylineOptions options; private Polyline polyline; private boolean clickable; @@ -53,6 +52,7 @@ public class PolylineProxy extends KrollProxy implements IShape private static final int MSG_SET_TOUCH_ENABLED = MSG_FIRST_ID + 504; private static final int MSG_SET_STROKE_PATTERN = MSG_FIRST_ID + 505; private static final int MSG_SET_STROKE_JOINT = MSG_FIRST_ID + 506; + private static final int MSG_SET_GEODESIC = MSG_FIRST_ID + 507; public static final String PROPERTY_STROKE_COLOR2 = "color"; public static final String PROPERTY_STROKE_WIDTH2 = "width"; @@ -60,6 +60,7 @@ public class PolylineProxy extends KrollProxy implements IShape public static final String PROPERTY_JOINT_TYPE = "jointType"; public static final String PROPERTY_ZINDEX = "zIndex"; + public static final String PROPERTY_GEODESIC = "geodesic"; private static final int DEFAULT_PATTERN_DASH_LENGTH_PX = 50; private static final int DEFAULT_PATTERN_GAP_LENGTH_PX = 20; @@ -79,8 +80,8 @@ public PolylineProxy() @Override public boolean handleMessage(Message msg) { - - AsyncResult result = null; + AsyncResult result; + switch (msg.what) { case MSG_SET_POINTS: { result = (AsyncResult) msg.obj; @@ -126,6 +127,12 @@ public boolean handleMessage(Message msg) result.setResult(null); return true; } + case MSG_SET_GEODESIC: { + result = (AsyncResult) msg.obj; + polyline.setGeodesic(TiConvert.toBoolean(result.getArg(), false)); + result.setResult(null); + return true; + } default: { return super.handleMessage(msg); } @@ -173,6 +180,10 @@ public void processOptions() clickable = TiConvert.toBoolean(getProperty(TiC.PROPERTY_TOUCH_ENABLED)); } + if (hasProperty(PolylineProxy.PROPERTY_GEODESIC)) { + options = options.geodesic(TiConvert.toBoolean(getProperty(PolylineProxy.PROPERTY_GEODESIC))); + } + if (hasProperty(PolylineProxy.PROPERTY_STROKE_PATTERN2)) { if (getProperty(PolylineProxy.PROPERTY_STROKE_PATTERN2) instanceof HashMap) { options.pattern( @@ -198,22 +209,31 @@ public void addLocation(Object loc, ArrayList locationArray, boolean lis } } - public ArrayList processPoints(Object points, boolean list) + public List processPoints(Object points, boolean list) { - ArrayList locationArray = new ArrayList(); - // encoded (result from routing API) - if (points instanceof String) { + + // Handle an array of points + if (points instanceof Object[]) { + Object[] pointsArray = (Object[]) points; + for (int i = 0; i < pointsArray.length; i++) { + Object obj = pointsArray[i]; + addLocation(obj, locationArray, list); + } + + return locationArray; + // Handle encoded polyline + } else if (points instanceof String) { List locationList = PolyUtil.decode((String) points); return new ArrayList(locationList); - } - // multiple points - if (points instanceof Object[]) { + // multiple points + } else if (points instanceof Object[]) { Object[] pointsArray = (Object[]) points; for (int i = 0; i < pointsArray.length; i++) { Object obj = pointsArray[i]; addLocation(obj, locationArray, list); } + return locationArray; } @@ -245,7 +265,6 @@ public Polyline getPolyline() @Override public void onPropertyChanged(String name, Object value) { - super.onPropertyChanged(name, value); Activity currentActivity = TiApplication.getAppCurrentActivity(); if (polyline == null) { @@ -283,8 +302,33 @@ else if (name.equals(PolylineProxy.PROPERTY_ZINDEX)) { else if (name.equals(TiC.PROPERTY_TOUCH_ENABLED)) { TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SET_TOUCH_ENABLED), - TiConvert.toBoolean(value)); + TiConvert.toBoolean(value)); } + + else if (name.equals(PolylineProxy.PROPERTY_GEODESIC)) { + TiMessenger.sendBlockingMainMessage(getMainHandler().obtainMessage(MSG_SET_GEODESIC), + TiConvert.toBoolean(value)); + } + } + + // A location can either be a an array of longitude, latitude pairings or + // an array of longitude, latitude objects. + // e.g. [123.33, 34.44], OR {longitude: 123.33, latitude, 34.44} + private LatLng parseLocation(Object loc) + { + LatLng location = null; + if (loc instanceof HashMap) { + HashMap point = (HashMap) loc; + location = new LatLng(TiConvert.toDouble(point.get(TiC.PROPERTY_LATITUDE)), + TiConvert.toDouble(point.get(TiC.PROPERTY_LONGITUDE))); + } else if (loc instanceof Object[]) { + Object[] temp = (Object[]) loc; + location = new LatLng(TiConvert.toDouble(temp[1]), TiConvert.toDouble(temp[0])); + } else if (loc instanceof LatLng) { + return (LatLng) loc; + } + + return location; } private List processPatternDefinition(HashMap definition) diff --git a/android/src/ti/map/TiUIMapView.java b/android/src/ti/map/TiUIMapView.java index f52b68c5..cc5c4fb1 100644 --- a/android/src/ti/map/TiUIMapView.java +++ b/android/src/ti/map/TiUIMapView.java @@ -9,7 +9,6 @@ import android.Manifest; import android.app.Activity; -import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; @@ -33,8 +32,11 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.LatLngBounds; import com.google.android.gms.maps.model.MapStyleOptions; +import com.google.android.gms.maps.model.PointOfInterest; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.android.gms.maps.model.Polyline; +import com.google.android.gms.maps.model.PolylineOptions; import com.google.maps.android.clustering.Cluster; import com.google.maps.android.clustering.ClusterManager; import com.google.maps.android.clustering.view.DefaultClusterRenderer; @@ -44,6 +46,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; + import org.appcelerator.kroll.KrollDict; import org.appcelerator.kroll.KrollProxy; import org.appcelerator.kroll.common.Log; @@ -60,14 +63,14 @@ import org.json.JSONTokener; import ti.map.Shape.Boundary; import ti.map.Shape.IShape; -import ti.map.Shape.PolylineBoundary; public class TiUIMapView extends TiUIFragment implements GoogleMap.OnMarkerClickListener, GoogleMap.OnMapClickListener, GoogleMap.OnMarkerDragListener, GoogleMap.OnInfoWindowClickListener, GoogleMap.InfoWindowAdapter, GoogleMap.OnMapLongClickListener, GoogleMap.OnMapLoadedCallback, OnMapReadyCallback, GoogleMap.OnCameraMoveStartedListener, GoogleMap.OnCameraMoveListener, GoogleMap.OnCameraIdleListener, GoogleMap.OnMyLocationChangeListener, - ClusterManager.OnClusterClickListener, ClusterManager.OnClusterItemClickListener + GoogleMap.OnPolylineClickListener, ClusterManager.OnClusterClickListener, ClusterManager.OnClusterItemClickListener, + GoogleMap.OnPoiClickListener { public static final String DEFAULT_COLLECTION_ID = "defaultCollection"; @@ -218,6 +221,7 @@ public void onMapReady(GoogleMap gMap) processPreloadCircles(); processPreloadPolylines(); processOverlaysList(); + map.setOnMarkerClickListener(mMarkerManager); map.setOnMapClickListener(this); if (!this.liteMode) { @@ -229,6 +233,8 @@ public void onMapReady(GoogleMap gMap) map.setOnMapLongClickListener(this); map.setOnMapLoadedCallback(this); map.setOnMyLocationChangeListener(this); + map.setOnPoiClickListener(this); + map.setOnPolylineClickListener(this); collection.setInfoWindowAdapter(this); collection.setOnInfoWindowClickListener(this); collection.setOnMarkerClickListener(this); @@ -284,22 +290,18 @@ public void processMapProperties(KrollDict d) Object[] annotations = (Object[]) d.get(TiC.PROPERTY_ANNOTATIONS); addAnnotations(annotations); } - if (d.containsKey(MapModule.PROPERTY_POLYGONS)) { Object[] polygons = (Object[]) d.get(MapModule.PROPERTY_POLYGONS); addPolygons(polygons); } - if (d.containsKey(MapModule.PROPERTY_POLYLINES)) { Object[] polylines = (Object[]) d.get(MapModule.PROPERTY_POLYLINES); addPolylines(polylines); } - if (d.containsKey(MapModule.PROPERTY_CIRCLES)) { Object[] circles = (Object[]) d.get(MapModule.PROPERTY_CIRCLES); addCircles(circles); } - if (d.containsKey(TiC.PROPERTY_ENABLE_ZOOM_CONTROLS)) { setZoomControlsEnabled(TiConvert.toBoolean(d, TiC.PROPERTY_ENABLE_ZOOM_CONTROLS, true)); } @@ -322,6 +324,9 @@ public void processMapProperties(KrollDict d) if (clusterRender != null) clusterRender.setMinClusterSize(d.getInt(MapModule.PROPERTY_MIN_CLUSTER_SIZE)); } + if (d.containsKey(TiC.PROPERTY_PADDING)) { + setPadding(d.getKrollDict(TiC.PROPERTY_PADDING)); + } } @Override @@ -363,7 +368,9 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP } else if (key.equals(MapModule.PROPERTY_MIN_CLUSTER_SIZE)) { if (clusterRender != null) clusterRender.setMinClusterSize(TiConvert.toInt(newValue, 4)); - } else { + } else if (key.equals(TiC.PROPERTY_PADDING)) { + setPadding(new KrollDict((HashMap) newValue)); + } else { super.propertyChanged(key, oldValue, newValue, proxy); } } @@ -406,15 +413,17 @@ protected void setStyle(String style) protected void setUserLocationEnabled(boolean enabled) { - Context context = TiApplication.getInstance().getApplicationContext(); + Activity currentActivity = TiApplication.getAppCurrentActivity(); if (map != null && (Build.VERSION.SDK_INT < 23 - || context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) + || currentActivity.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED + || currentActivity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { map.setMyLocationEnabled(enabled); } else { - Log.e(TAG, "Enable ACCESS_FINE_LOCATION permission to use userLocation"); + Log.e(TAG, "Enable ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission to use userLocation"); } } @@ -476,15 +485,20 @@ protected void setTrafficEnabled(boolean enabled) } } - protected void setPadding(int left, int top, int right, int bottom) + protected void setPadding(KrollDict args) { + int left = TiConvert.toInt(args.getInt(TiC.PROPERTY_LEFT), 0); + int top = TiConvert.toInt(args.getInt(TiC.PROPERTY_TOP), 0); + int right = TiConvert.toInt(args.getInt(TiC.PROPERTY_RIGHT), 0); + int bottom = TiConvert.toInt(args.getInt(TiC.PROPERTY_BOTTOM), 0); + if (map != null) { map.setPadding(left, top, right, bottom); } } - protected void showAnnotations(Object[] annotations) - { + protected void showAnnotations(Object[] annotations, int padding, boolean animated) + { ArrayList markers = new ArrayList(); // Use supplied annotations first. If none available, select all (parity with iOS) @@ -499,15 +513,28 @@ protected void showAnnotations(Object[] annotations) markers = timarkers; } - LatLngBounds.Builder builder = new LatLngBounds.Builder(); - for (TiMarker marker : markers) { - builder.include(marker.getPosition()); - } - LatLngBounds bounds = builder.build(); + try { + // Make sure to have markers to prevent uncaught exceptions + if (markers.size() > 0) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + for (TiMarker marker : markers) { + if (marker != null) { + builder.include(marker.getPosition()); + } + } + LatLngBounds bounds = builder.build(); + + CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, padding); - int padding = 30; - CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); - map.animateCamera(cu); + if (animated) { + map.animateCamera(cameraUpdate); + } else { + map.moveCamera(cameraUpdate); + } + } + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + } } protected void setZoomControlsEnabled(boolean enabled) @@ -784,7 +811,13 @@ public void addRoute(RouteProxy r) } r.processOptions(); - r.setRoute(map.addPolyline(r.getOptions())); + r.setRoute( createPolyLine(r.getOptions()) ); + } + + private Polyline createPolyLine(PolylineOptions polylineOptions) { + Polyline polyline = map.addPolyline(polylineOptions); + polyline.setClickable(true); + return polyline; } public void removeRoute(RouteProxy r) @@ -856,8 +889,7 @@ public void addPolyline(PolylineProxy p) return; } p.processOptions(); - p.setPolyline(map.addPolyline(p.getOptions())); - + p.setPolyline( createPolyLine(p.getOptions()) ); currentPolylines.add(p); } @@ -1041,6 +1073,20 @@ public void fireLongClickEvent(LatLng point) } } + public void firePOIClickEvent(PointOfInterest poi) + { + KrollDict d = new KrollDict(); + d.put(TiC.PROPERTY_LATITUDE, poi.latLng.latitude); + d.put(TiC.PROPERTY_LONGITUDE, poi.latLng.longitude); + d.put(TiC.PROPERTY_NAME, poi.name); + d.put(MapModule.PROPERTY_PLACE_ID, poi.placeId); + d.put(TiC.PROPERTY_TYPE, MapModule.EVENT_POI_CLICK); + d.put(TiC.PROPERTY_SOURCE, proxy); + if (proxy != null) { + proxy.fireEvent(MapModule.EVENT_POI_CLICK, d); + } + } + public void firePinChangeDragStateEvent(Marker marker, AnnotationProxy annoProxy, int dragState) { KrollDict d = new KrollDict(); @@ -1157,7 +1203,7 @@ public void onMapClick(LatLng point) clickableCircles.clear(); } - // currentPolygons + // currentPolygons ArrayList clickablePolygones = new ArrayList(); for (PolygonProxy polygonProxy : currentPolygons) { if (polygonProxy.getClickable()) { @@ -1165,7 +1211,6 @@ public void onMapClick(LatLng point) } } if (clickablePolygones.size() > 0) { - Boundary boundary = new Boundary(); ArrayList clickedPolygon = boundary.contains(clickablePolygones, point); boundary = null; @@ -1178,37 +1223,6 @@ public void onMapClick(LatLng point) clickablePolygones.clear(); } - // currentPolylines - ArrayList clickablePolylines = new ArrayList(); - for (PolylineProxy polylineProxy : currentPolylines) { - if (polylineProxy.getClickable()) { - clickablePolylines.add(polylineProxy); - } - } - - if (map != null && clickablePolylines.size() > 0) { - PolylineBoundary boundary = new PolylineBoundary(); - - LatLngBounds b = map.getProjection().getVisibleRegion().latLngBounds; - double side1 = b.northeast.latitude > b.southwest.latitude ? (b.northeast.latitude - b.southwest.latitude) - : (b.southwest.latitude - b.northeast.latitude); - double side2 = b.northeast.longitude > b.southwest.longitude - ? (b.northeast.longitude - b.southwest.longitude) - : (b.southwest.longitude - b.northeast.longitude); - double diagonal = Math.sqrt((side1 * side1) + (side2 * side2)); - double val = diagonal / map.getCameraPosition().zoom; - - ArrayList clickedPolylines = boundary.contains(clickablePolylines, point, val); - - boundary = null; - if (clickedPolylines.size() > 0) { - for (PolylineProxy polylineProxy : clickedPolylines) { - fireShapeClickEvent(point, polylineProxy, MapModule.PROPERTY_POLYLINE); - } - } - } - clickablePolylines.clear(); - KrollDict d = new KrollDict(); d.put(TiC.PROPERTY_LATITUDE, point.latitude); d.put(TiC.PROPERTY_LONGITUDE, point.longitude); @@ -1218,6 +1232,12 @@ public void onMapClick(LatLng point) } } + @Override + public void onPoiClick(PointOfInterest poi) + { + firePOIClickEvent(poi); + } + @Override public void onMapLongClick(LatLng point) { @@ -1356,6 +1376,7 @@ public void onCameraIdle() d.put(TiC.PROPERTY_LATITUDE, position.target.latitude); d.put(TiC.PROPERTY_LONGITUDE, position.target.longitude); d.put(TiC.PROPERTY_SOURCE, proxy); + d.put(MapModule.PROPERTY_ZOOM, position.zoom); LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; d.put(TiC.PROPERTY_LATITUDE_DELTA, (bounds.northeast.latitude - bounds.southwest.latitude)); d.put(TiC.PROPERTY_LONGITUDE_DELTA, (bounds.northeast.longitude - bounds.southwest.longitude)); @@ -1447,4 +1468,31 @@ public boolean onClusterItemClick(TiMarker tiMarker) { return onMarkerClick(tiMarker.getMarker()); } + + @Override + public void onPolylineClick(Polyline polyline) { + final String id = polyline.getId(); + + // find the proxy for this polyline + PolylineProxy polylineProxy = null; + for (PolylineProxy tempPolylineProxy : currentPolylines) { + if (tempPolylineProxy.getPolyline().getId().equals(id)) { + polylineProxy = tempPolylineProxy; + break; + } + } + + KrollDict d = new KrollDict(); + d.put(TiC.EVENT_PROPERTY_CLICKSOURCE, MapModule.PROPERTY_POLYLINE); + d.put(TiC.PROPERTY_ANNOTATION, false); + d.put("overlay", polylineProxy); + + d.put(MapModule.PROPERTY_MAP, proxy); + d.put(TiC.PROPERTY_TYPE, TiC.EVENT_CLICK); + d.put(TiC.PROPERTY_SOURCE, polylineProxy); + + if (proxy != null) { + proxy.fireEvent(TiC.EVENT_CLICK, d); + } + } } diff --git a/android/src/ti/map/ViewProxy.java b/android/src/ti/map/ViewProxy.java index a09b9faf..fe095d80 100644 --- a/android/src/ti/map/ViewProxy.java +++ b/android/src/ti/map/ViewProxy.java @@ -7,14 +7,23 @@ package ti.map; import android.app.Activity; +import android.graphics.Color; import android.os.Message; import com.google.android.gms.maps.CameraUpdate; +import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.TileOverlay; import com.google.android.gms.maps.model.TileOverlayOptions; +import com.google.android.gms.maps.model.Dash; +import com.google.android.gms.maps.model.Gap; +import com.google.android.gms.maps.model.LatLngBounds; +import com.google.android.gms.maps.model.PatternItem; +import com.google.android.gms.maps.model.PolylineOptions; +import com.google.maps.android.SphericalUtil; import com.google.maps.android.heatmaps.HeatmapTileProvider; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -38,8 +47,8 @@ propertyAccessors = { TiC.PROPERTY_USER_LOCATION, MapModule.PROPERTY_USER_LOCATION_BUTTON, TiC.PROPERTY_MAP_TYPE, TiC.PROPERTY_REGION, TiC.PROPERTY_ANNOTATIONS, TiC.PROPERTY_ANIMATE, MapModule.PROPERTY_TRAFFIC, TiC.PROPERTY_STYLE, TiC.PROPERTY_ENABLE_ZOOM_CONTROLS, - MapModule.PROPERTY_COMPASS_ENABLED, MapModule.PROPERTY_SCROLL_ENABLED, - MapModule.PROPERTY_ZOOM_ENABLED, MapModule.PROPERTY_POLYLINES }) + MapModule.PROPERTY_COMPASS_ENABLED, MapModule.PROPERTY_SCROLL_ENABLED, MapModule.PROPERTY_ZOOM_ENABLED, + MapModule.PROPERTY_POLYLINES, TiC.PROPERTY_PADDING }) public class ViewProxy extends TiViewProxy implements AnnotationDelegate { private static final String TAG = "MapViewProxy"; @@ -326,7 +335,7 @@ public boolean handleMessage(Message msg) case MSG_SHOW_ANNOTATIONS: { result = ((AsyncResult) msg.obj); - handleShowAnnotations(result.getArg()); + handleShowAnnotations((Object[]) result.getArg(), 30, false); result.setResult(null); return true; } @@ -340,10 +349,10 @@ public boolean handleMessage(Message msg) case MSG_CONTAINS_COORDINATE: { result = ((AsyncResult) msg.obj); - result.setResult(Boolean.valueOf(handleContainsCoordinate((KrollDict) result.getArg()))); + result.setResult(handleContainsCoordinate((KrollDict) result.getArg())); return true; } - + default: { return super.handleMessage(msg); } @@ -445,17 +454,17 @@ private void handleSnapshot() } @Kroll.method - public void showAnnotations(Object annotations) - { + public void showAnnotations(Object annotations, int padding, boolean animated) + { if (TiApplication.isUIThread()) { - handleShowAnnotations(annotations); + handleShowAnnotations(annotations, padding, animated); } else { getMainHandler().obtainMessage(MSG_SHOW_ANNOTATIONS).sendToTarget(); } } - private void handleShowAnnotations(Object annotations) - { + private void handleShowAnnotations(Object annotations, int padding, boolean animated) + { if (!(annotations instanceof Object[])) { Log.e(TAG, "Invalid argument to addAnnotations", Log.DEBUG_MODE); return; @@ -463,8 +472,8 @@ private void handleShowAnnotations(Object annotations) Object[] annos = (Object[]) annotations; TiUIMapView mapView = (TiUIMapView) peekView(); - if (mapView.getMap() != null) { - mapView.showAnnotations(annos); + if (mapView != null && mapView.getMap() != null) { + mapView.showAnnotations(annos, padding, animated); } } @@ -1073,6 +1082,72 @@ public void removeAllPolylines() } } + + @Kroll.method + public KrollDict drawRoundedPolylineBetweenCoordinates(KrollDict args) + { + // Algorithm credits https://stackoverflow.com/a/43665433/5537752 + + KrollDict[] jsCoordinates = args.getKrollDictArray("coordinates"); + KrollDict jsOptions = args.getKrollDict("options"); + + LatLng p1 = new LatLng(jsCoordinates[0].getDouble("latitude").doubleValue(), jsCoordinates[0].getDouble("longitude").doubleValue()); + LatLng p2 = new LatLng(jsCoordinates[1].getDouble("latitude").doubleValue(), jsCoordinates[1].getDouble("longitude").doubleValue()); + + double k = 0.25; + + // Calculate distance and heading between two points + double d = SphericalUtil.computeDistanceBetween(p1,p2); + double h = SphericalUtil.computeHeading(p1, p2); + + // Midpoint position + LatLng p = SphericalUtil.computeOffset(p1, d * 0.5, h); + + // Apply some mathematics to calculate position of the circle center + double x = (1 - k * k) * d * 0.5 / (2 * k); + double r = (1 + k * k) * d * 0.5 / (2 * k); + + LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0); + + // Polyline options + PolylineOptions options = new PolylineOptions(); + + // Calculate heading between circle center and two points + double h1 = SphericalUtil.computeHeading(c, p1); + double h2 = SphericalUtil.computeHeading(c, p2); + + // Calculate positions of points on circle border and add them to polyline options + int numPoints = 100; + double step = (h2 - h1) / numPoints; + + for (int i = 0; i < numPoints; i++) { + LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step); + options.add(pi); + } + + int strokeWidth = 3; + if (jsOptions != null && jsOptions.containsKey("strokeWidth")) { + strokeWidth = jsOptions.getInt("strokeWidth"); + } + + // Draw polyline + TiUIMapView mapView = (TiUIMapView) peekView(); + mapView.getMap().addPolyline(options.width(strokeWidth).color(Color.BLACK).geodesic(false)); + + // Bound to coordinates + LatLngBounds bounds = new LatLngBounds.Builder().include(p1).include(p2).build(); + CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 20); + mapView.getMap().moveCamera(cameraUpdate); + + // Return center coordinate + LatLng centerCoordinate = options.getPoints().get(49); + KrollDict centerCoordinateDict = new KrollDict(); + centerCoordinateDict.put("latitude", centerCoordinate.latitude); + centerCoordinateDict.put("longitude", centerCoordinate.longitude); + + return centerCoordinateDict; + } + /** * EOF Polylines */ @@ -1199,6 +1274,20 @@ public void handleZoom(int delta) } } + @Kroll.method + public boolean containsCoordinate(KrollDict coordinate) + { + return handleContainsCoordinate(coordinate); + } + + private boolean handleContainsCoordinate(KrollDict coordinate) { + TiUIView view = peekView(); + if ((view instanceof TiUIMapView)) { + return ((TiUIMapView)view).containsCoordinate(coordinate); + } + return false; + } + // clang-format off @Kroll.method @Kroll.getProperty @@ -1215,11 +1304,16 @@ public float getZoomLevel() private float handleGetZoomLevel() { TiUIView view = peekView(); + if (view instanceof TiUIMapView) { - return ((TiUIMapView) view).getMap().getCameraPosition().zoom; - } else { - return 0; + GoogleMap mapView = ((TiUIMapView) view).getMap(); + + if (mapView != null) { + return mapView.getCameraPosition().zoom; + } } + + return 0; } @Kroll.method @@ -1359,19 +1453,6 @@ public void refreshAnnotation(AnnotationProxy annotation) } } - // clang-format off - @Kroll.method - @Kroll.setProperty - public void setPadding(KrollDict padding) - // clang-format on - { - if (TiApplication.isUIThread()) { - handleSetPadding(padding); - } else { - getMainHandler().obtainMessage(MSG_SET_PADDING, padding).sendToTarget(); - } - } - private void addPreloadImageOverlay(ImageOverlayProxy proxy) { if (!(preloadOverlaysList.contains(proxy))) { @@ -1479,33 +1560,11 @@ private void handleRemoveAllImageOverlays() } } - @Kroll.method - public boolean containsCoordinate(KrollDict coordinate) - { - return handleContainsCoordinate(coordinate); - } - - private boolean handleContainsCoordinate(KrollDict coordinate) - { - TiUIView view = peekView(); - - if ((view instanceof TiUIMapView)) { - return ((TiUIMapView) view).containsCoordinate(coordinate); - } - - return false; - } - public void handleSetPadding(KrollDict args) { TiUIView view = peekView(); if (view instanceof TiUIMapView) { - int left = TiConvert.toInt(args.getInt(TiC.PROPERTY_LEFT), 0); - int top = TiConvert.toInt(args.getInt(TiC.PROPERTY_TOP), 0); - int right = TiConvert.toInt(args.getInt(TiC.PROPERTY_RIGHT), 0); - int bottom = TiConvert.toInt(args.getInt(TiC.PROPERTY_BOTTOM), 0); - - ((TiUIMapView) view).setPadding(left, top, right, bottom); + ((TiUIMapView) view).setPadding(args); } } diff --git a/apidoc/View.yml b/apidoc/View.yml index cb75737c..279195b1 100644 --- a/apidoc/View.yml +++ b/apidoc/View.yml @@ -496,6 +496,31 @@ events: type: Number since: "6.2.0" + - name: poiclick + summary: | + Fired when the user clicks on a point of interest on the map. + description: | + The `poiclick` event is fired when the user clicks on a point of interest of the map and returns + the longitude/latitude and name of that location. + properties: + - name: name + summary: The name of the point of interest. + type: String + + - name: placeID + summary: The Google place ID of the point of interest. + type: String + + - name: latitude + summary: The latitude of the clicked position. + type: Number + + - name: longitude + summary: The longitude of the clicked position. + type: Number + since: "8.1.0" + platforms: [android] + - name: regionwillchange since: { android: "6.2.0", iphone: "6.0.0", ipad: "6.0.0", macos: "9.2.0" } summary: | diff --git a/ios/Classes/TiMapAnnotationProxy.m b/ios/Classes/TiMapAnnotationProxy.m index 93466501..f8e74f1e 100644 --- a/ios/Classes/TiMapAnnotationProxy.m +++ b/ios/Classes/TiMapAnnotationProxy.m @@ -305,6 +305,8 @@ - (void)setLeftView:(id)leftview } } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" - (void)setPreviewContext:(id)previewContext { Class TiUIiOSPreviewContextProxy = NSClassFromString(@"TiUIiOSPreviewContextProxy"); @@ -333,6 +335,7 @@ - (void)setPreviewContext:(id)previewContext [self setNeedsRefreshingWithSelection:YES]; } } +#pragma clang diagnostic pop - (void)setImage:(id)image { diff --git a/ios/Classes/TiMapCircleProxy.m b/ios/Classes/TiMapCircleProxy.m index 879afa2a..e6d51e79 100644 --- a/ios/Classes/TiMapCircleProxy.m +++ b/ios/Classes/TiMapCircleProxy.m @@ -98,7 +98,7 @@ - (void)setFillColor:(id)value if (fillColor != nil) { RELEASE_TO_NIL(fillColor); } - fillColor = [[TiColor colorNamed:value] retain]; + fillColor = [[TiUtils colorValue:value] retain]; [[self circleRenderer] setFillColor:(fillColor == nil ? [UIColor blackColor] : [fillColor color])]; [self replaceValue:value forKey:@"fillColor" notification:NO]; } @@ -108,7 +108,7 @@ - (void)setStrokeColor:(id)value if (strokeColor != nil) { RELEASE_TO_NIL(strokeColor); } - strokeColor = [[TiColor colorNamed:value] retain]; + strokeColor = [[TiUtils colorValue:value] retain]; [[self circleRenderer] setStrokeColor:(strokeColor == nil ? [UIColor blackColor] : [strokeColor color])]; [self replaceValue:value forKey:@"strokeColor" notification:NO]; } diff --git a/ios/Classes/TiMapImageOverlayRenderer.h b/ios/Classes/TiMapImageOverlayRenderer.h index 6090e3bd..16656cde 100644 --- a/ios/Classes/TiMapImageOverlayRenderer.h +++ b/ios/Classes/TiMapImageOverlayRenderer.h @@ -6,6 +6,7 @@ */ #import +#import @interface TiMapImageOverlayRenderer : MKOverlayRenderer diff --git a/ios/Classes/TiMapModuleAssets.m b/ios/Classes/TiMapModuleAssets.m index 1f348e39..a169d2dd 100644 --- a/ios/Classes/TiMapModuleAssets.m +++ b/ios/Classes/TiMapModuleAssets.m @@ -3,18 +3,20 @@ */ #import "TiMapModuleAssets.h" -extern NSData *filterDataInRange(NSData *thedata, NSRange range); +extern NSData* filterDataInRange(NSData* thedata, NSRange range); @implementation TiMapModuleAssets - (NSData *)moduleAsset { + return nil; } - (NSData *)resolveModuleAsset:(NSString *)path { + return nil; } diff --git a/ios/Classes/TiMapPolygonProxy.m b/ios/Classes/TiMapPolygonProxy.m index 975c866d..57a3b534 100644 --- a/ios/Classes/TiMapPolygonProxy.m +++ b/ios/Classes/TiMapPolygonProxy.m @@ -99,6 +99,8 @@ - (CLLocationCoordinate2D)processLocation:(id)locObj CLLocationDegrees lon = [TiUtils doubleValue:[locObj objectAtIndex:0]]; return CLLocationCoordinate2DMake(lat, lon); + } else { + [self throwException:@"Invalid coordinate tyoe" subreason:@"Use either a dictionary or array" location:CODELOCATION]; } return kCLLocationCoordinate2DInvalid; @@ -141,7 +143,7 @@ - (void)setFillColor:(id)value if (fillColor != nil) { RELEASE_TO_NIL(fillColor); } - fillColor = [[TiColor colorNamed:value] retain]; + fillColor = [[TiUtils colorValue:value] retain]; [self applyFillColor]; } @@ -150,7 +152,7 @@ - (void)setStrokeColor:(id)value if (strokeColor != nil) { RELEASE_TO_NIL(strokeColor); } - strokeColor = [[TiColor colorNamed:value] retain]; + strokeColor = [[TiUtils colorValue:value] retain]; [self applyStrokeColor]; } diff --git a/ios/Classes/TiMapPolylineProxy.h b/ios/Classes/TiMapPolylineProxy.h index 8d81c2e2..ef70becb 100644 --- a/ios/Classes/TiMapPolylineProxy.h +++ b/ios/Classes/TiMapPolylineProxy.h @@ -5,14 +5,13 @@ * Please see the LICENSE included with this distribution for details. */ -#ifndef map_TiMapPolylineProxy_h -#define map_TiMapPolylineProxy_h - #import "TiMapOverlayPattern.h" #import #import +#import #import +#import "TiMapOverlayPattern.h" @class TiMapViewProxy; @@ -29,5 +28,3 @@ @property (nonatomic, readonly) MKPolylineRenderer *polylineRenderer; @end - -#endif diff --git a/ios/Classes/TiMapPolylineProxy.m b/ios/Classes/TiMapPolylineProxy.m index 611b150d..ed8c7faf 100644 --- a/ios/Classes/TiMapPolylineProxy.m +++ b/ios/Classes/TiMapPolylineProxy.m @@ -74,6 +74,8 @@ - (CLLocationCoordinate2D)processLocation:(id)locObj CLLocationDegrees lon = [TiUtils doubleValue:[locObj objectAtIndex:0]]; return CLLocationCoordinate2DMake(lat, lon); + } else { + [self throwException:@"Invalid coordinate tyoe" subreason:@"Use either a dictionary or array" location:CODELOCATION]; } return kCLLocationCoordinate2DInvalid; @@ -128,7 +130,7 @@ - (void)setStrokeColor:(id)value if (strokeColor != nil) { RELEASE_TO_NIL(strokeColor); } - strokeColor = [[TiColor colorNamed:value] retain]; + strokeColor = [[TiUtils colorValue:value] retain]; [self applyStrokeColor]; [self replaceValue:value forKey:@"strokeColor" notification:NO]; } diff --git a/ios/Classes/TiMapRouteProxy.m b/ios/Classes/TiMapRouteProxy.m index db3b7960..1eaf2d7a 100644 --- a/ios/Classes/TiMapRouteProxy.m +++ b/ios/Classes/TiMapRouteProxy.m @@ -101,7 +101,7 @@ - (void)setColor:(id)value if (color != nil) { RELEASE_TO_NIL(color); } - color = [[TiColor colorNamed:value] retain]; + color = [[TiUtils colorValue:value] retain]; [self applyColor]; } diff --git a/ios/Classes/TiMapSnapshotterProxy.m b/ios/Classes/TiMapSnapshotterProxy.m index a9fc6602..188c2855 100644 --- a/ios/Classes/TiMapSnapshotterProxy.m +++ b/ios/Classes/TiMapSnapshotterProxy.m @@ -97,6 +97,7 @@ - (void)takeSnapshot:(id)args NSDictionary *event = [NSDictionary dictionaryWithObject:blob forKey:@"image"]; [self _fireEventToListener:@"blob" withObject:event listener:successCallback thisObject:nil]; + RELEASE_TO_NIL(blob); }]; } diff --git a/ios/Classes/TiMapView.h b/ios/Classes/TiMapView.h index d241e183..9cf5d79e 100644 --- a/ios/Classes/TiMapView.h +++ b/ios/Classes/TiMapView.h @@ -91,12 +91,12 @@ - (void)addImageOverlays:(id)args; - (void)removeImageOverlay:(id)arg; - (void)removeAllImageOverlays; +- (NSNumber *)containsCoordinate:(id)coordinate; - (void)firePinChangeDragState:(MKAnnotationView *)pinview newState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState; - (void)setClusterAnnotation:(TiMapAnnotationProxy *)annotation forMembers:(NSArray *)members; - (void)animateAnnotation:(TiMapAnnotationProxy *)newAnnotation withLocation:(CLLocationCoordinate2D)newLocation; - (void)setLocation:(id)location; -- (NSNumber *)containsCoordinate:(id)args; #pragma mark Utils - (void)addOverlay:(MKPolyline *)polyline level:(MKOverlayLevel)level; diff --git a/ios/Classes/TiMapView.m b/ios/Classes/TiMapView.m index 46ed4380..8846393f 100644 --- a/ios/Classes/TiMapView.m +++ b/ios/Classes/TiMapView.m @@ -47,6 +47,7 @@ - (void)dealloc RELEASE_TO_NIL(circleProxies); RELEASE_TO_NIL(imageOverlayProxies); RELEASE_TO_NIL(clusterAnnotations); + [super dealloc]; } @@ -1273,6 +1274,8 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap annView.userInteractionEnabled = YES; annView.tag = [ann tag]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" id previewContext = [ann valueForUndefinedKey:@"previewContext"]; if (previewContext && [TiUtils forceTouchSupported] && [previewContext performSelector:@selector(preview)] != nil) { UIViewController *controller = [[[TiApp app] controller] topPresentedController]; @@ -1338,7 +1341,8 @@ - (MKClusterAnnotation *)mapView:(MKMapView *)mapView clusterAnnotationForMember if ([mapProxy _hasListeners:@"clusterstart"]) { [mapProxy fireEvent:@"clusterstart" withObject:event]; } - return annotation; + + return [annotation autorelease]; } // mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map. @@ -1396,6 +1400,18 @@ - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views return result; } +- (NSNumber *)containsCoordinate:(id)coordinate +{ + ENSURE_SINGLE_ARG(coordinate, NSDictionary); + + CLLocationDegrees latitude = [TiUtils doubleValue:coordinate[@"latitude"]]; + CLLocationDegrees longitude = [TiUtils doubleValue:coordinate[@"longitude"]]; + + CLLocationCoordinate2D nativeCoordinate = CLLocationCoordinate2DMake(latitude, longitude); + + return @(MKMapRectContainsPoint(map.visibleMapRect, MKMapPointForCoordinate(nativeCoordinate))); +} + #pragma mark Event generation - (void)handleCalloutTap:(UIGestureRecognizer *)sender @@ -1612,19 +1628,4 @@ - (void)doClickEvent:(id)viewProxy mapProxy:(id)mapProxy event:(NSDictionary *)e } } -- (NSNumber *)containsCoordinate:(id)args -{ - ENSURE_SINGLE_ARG(args, NSDictionary); - - if (!self.map) { - return @(NO); - } - - CLLocationCoordinate2D coordinate; - coordinate.latitude = [TiUtils doubleValue:args[@"latitude"]]; - coordinate.longitude = [TiUtils doubleValue:args[@"longitude"]]; - - return @(MKMapRectContainsPoint(self.map.visibleMapRect, MKMapPointForCoordinate(coordinate))); -} - @end diff --git a/ios/Classes/TiMapViewProxy.h b/ios/Classes/TiMapViewProxy.h index a479d522..71fc970d 100644 --- a/ios/Classes/TiMapViewProxy.h +++ b/ios/Classes/TiMapViewProxy.h @@ -65,7 +65,6 @@ - (void)removeImageOverlay:(id)arg; - (void)removeAllImageOverlays:(id)args; - (void)setClusterAnnotation:(id)args; -- (void)setLocation:(id)location; -- (NSNumber *)containsCoordinate:(id)args; +- (NSNumber *)containsCoordinate:(id)coordinate; @end diff --git a/ios/Classes/TiMapViewProxy.m b/ios/Classes/TiMapViewProxy.m index c64dc204..1a0bd05a 100644 --- a/ios/Classes/TiMapViewProxy.m +++ b/ios/Classes/TiMapViewProxy.m @@ -179,6 +179,11 @@ - (MKAnnotationView *)viewForAnnotationProxy:(TiMapAnnotationProxy *)annotationP #pragma mark Public API +- (NSNumber *)mapType +{ + return @(((TiMapView *)[self view]).map.mapType); +} + - (void)zoom:(id)arg { ENSURE_SINGLE_ARG(arg, NSObject); @@ -888,7 +893,7 @@ - (void)setClusterAnnotation:(id)args } } -#pragma mark Public APIs iOS 7 +#pragma mark Public API's - (TiMapCameraProxy *)camera { @@ -924,9 +929,9 @@ - (void)showAnnotations:(id)args NO); } -- (NSNumber *)containsCoordinate:(id)args +- (NSNumber *)containsCoordinate:(id)coordinate { - return [(TiMapView *)[self view] containsCoordinate:args]; + return [(TiMapView *)[self view] containsCoordinate:coordinate]; } @end diff --git a/ios/documentation/changelog.md b/ios/documentation/changelog.md deleted file mode 100644 index d9669209..00000000 --- a/ios/documentation/changelog.md +++ /dev/null @@ -1,40 +0,0 @@ -# Change Log - -⚠️ Important note: This changelog has been replaced by the official Github [releases tab](https://github.com/appcelerator-modules/ti.map/releases). - -``` -v2.12.0 Support peek-and-pop in annotations [TIMOB-24375] -v2.11.0 Support for overlay patterns [MOD-2346] -v2.10.0 Support "touchEnabled" for overlays, add "mapclick" event [MOD-2322], [MOD-2268] -v2.9.0 Support "opacity" for circles -v2.5.0 Add iOS 9 mapTypes 'HYBRID_FLYOVER_TYPE' and 'SATELLITE_FLYOVER_TYPE'. [MOD-2152] -v2.4.1 Fixed an issue where pins have not been draggable anymore. [MOD-2131] -v2.4.0 iOS 9: Upgrade map module to support bitcode. [TIMOB-19385] -v2.3.2 Fixed map crash with polygons when not setting mapType. [TIMOB-19102] -v2.3.1 Add drawing support. Includes polygons, polylines, and circles. [TIMOB-15410] - Fixes longclick event on iOS. [Github #41] -v2.2.2 Fixed map annotations showing undeclared buttons in iOS7 [TIMOB-17953] - -v2.2.1 Fixed map draggable map pins [TIMOB-18510] - -v2.2.0 Updated to build for 64-bit [TIMOB-17928] - Adding architectures to manifest [TIMOB-18065] - -v2.0.6 Fixed map not responding to touch after animating camera [TIMOB-17749] - -v2.0.5 Fixed exception when setting "centerCoordinate" on camera [TIMOB-17659] - -v2.0.4 Fixed "userLocation" permissions for iOS 8 [TIMOB-17665] - Bumping minsdk to 3.4.0 [MOD-1968] - -v2.0.2 Fixed ignoring userLocation property during view creation [TIMOB-12733] - -v2.0.1 Fixed annotation not showing leftButton rightButton [TC-3524] - -v2.0.0 Fixed methods deprecated in iOS 7 [MOD-1521] - Add Support for iOS7 MapCamera [MOD-1523] - Expose new iOS7 properties and methods of MapView [MOD-1522] - Fixed map view with percentage values become grayed when rotating the screen [MOD-1613] - -v1.0.0 Moved out of the Titanium SDK to a standalone module [MOD-1514] -``` diff --git a/ios/documentation/index.md b/ios/documentation/index.md deleted file mode 100644 index ef44f285..00000000 --- a/ios/documentation/index.md +++ /dev/null @@ -1,47 +0,0 @@ -# ti.map Module - -## Description - -The Map module allows you to access Apple's MapKit APIs - -## Accessing the map Module - -To access this module from JavaScript, you would do the following: - - var Map = require("ti.map"); - -The `Map` variable is a reference to the Module object. - -## Getting Started - -View the [Using Titanium Modules](http://docs.appcelerator.com/platform/latest/#!/guide/Using_Titanium_Modules) document for instructions on getting -started with using this module in your application. - -## Requirements - -Must be run using a Titanium SDK that has had Maps removed. Running against a version of the SDK that still has the Maps module will result in a build failure. - -Applications using this module must be built using Xcode 5 or later. - -## Usage - -See documentation - -## Documentation -* [Map Module API Reference Documentation](http://docs.appcelerator.com/platform/latest/#!/api/Modules.Map) - -## Author - -Jeff Haynie & Jon Alter - -## Module History - -View the [change log](changelog.html) for this module. - -## Feedback and Support - -Please direct all questions, feedback, and concerns to [info@appcelerator.com](mailto:info@appcelerator.com?subject=iOS%20Map%20Module). - -## License - -Copyright(c) 2013 by Appcelerator, Inc. All Rights Reserved. Please see the LICENSE file included in the distribution for further details.