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/build.gradle b/android/build.gradle
index a057a92d..a9172ed4 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -1,6 +1,11 @@
dependencies {
- implementation 'com.google.android.gms:play-services-maps:17.0.0'
- implementation 'com.google.maps.android:android-maps-utils:0.6.2'
- implementation 'androidx.fragment:fragment:1.1.0'
+ // https://developers.google.com/android/guides/releases
+ implementation 'com.google.android.gms:play-services-maps:18.1.0'
+
+ // https://github.com/googlemaps/android-maps-utils/releases
+ implementation 'com.google.maps.android:android-maps-utils:2.4.0'
+
+ // https://developer.android.com/jetpack/androidx/releases/fragment
+ implementation 'androidx.fragment:fragment:1.5.2'
}
diff --git a/android/example/app.js b/android/example/app.js
index 060efb3d..e7473e5e 100644
--- a/android/example/app.js
+++ b/android/example/app.js
@@ -1,7 +1,4 @@
-var IOS = (Ti.Platform.osname === 'iphone' || Ti.Platform.osname === 'ipad');
-var ANDROID = (Ti.Platform.osname === 'android');
-var UI = require('ui');
-var Map = require('ti.map');
+const Map = require('ti.map');
//=====================================================================
// Rows
@@ -14,19 +11,4 @@ var rows = [
require('tests/drawing')
];
-if (IOS) {
- rows.push(require('tests/camera'));
- rows.push(require('tests/properties'));
-}
-
-if (ANDROID && Map.isGooglePlayServicesAvailable() != Map.SUCCESS) {
- alert ("Google Play Services is not installed/updated/available");
-} else {
- startUI();
-}
-
-function startUI() {
- UI.init(rows, function(e) {
- rows[e.index].run && rows[e.index].run(UI, Map);
- });
-}
+win.open();
\ No newline at end of file
diff --git a/android/manifest b/android/manifest
index ad02390d..7fad7c3d 100644
--- a/android/manifest
+++ b/android/manifest
@@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
-version: 5.0.2
+version: 5.1.0
apiversion: 4
architectures: arm64-v8a armeabi-v7a x86 x86_64
description: External version of Map module using native Google Maps library
diff --git a/android/platform/android/res/drawable/pin_waypoint.xml b/android/platform/android/res/drawable/pin_waypoint.xml
new file mode 100644
index 00000000..fe1c2c29
--- /dev/null
+++ b/android/platform/android/res/drawable/pin_waypoint.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/android/platform/android/res/layout/ti_map.xml b/android/platform/android/res/layout/ti_map.xml
new file mode 100644
index 00000000..b6ed0ae4
--- /dev/null
+++ b/android/platform/android/res/layout/ti_map.xml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/android/platform/android/res/layout/ti_map_raw.xml b/android/platform/android/res/layout/ti_map_raw.xml
new file mode 100644
index 00000000..e00240e0
--- /dev/null
+++ b/android/platform/android/res/layout/ti_map_raw.xml
@@ -0,0 +1,8 @@
+
+
\ No newline at end of file
diff --git a/android/platform/android/res/values/dimensions.xml b/android/platform/android/res/values/dimensions.xml
new file mode 100644
index 00000000..cd58743d
--- /dev/null
+++ b/android/platform/android/res/values/dimensions.xml
@@ -0,0 +1,3 @@
+
+ 20dp
+
\ No newline at end of file
diff --git a/android/src/ti/map/AnnotationProxy.java b/android/src/ti/map/AnnotationProxy.java
index 8d1456f5..9800ed42 100644
--- a/android/src/ti/map/AnnotationProxy.java
+++ b/android/src/ti/map/AnnotationProxy.java
@@ -8,15 +8,30 @@
import android.animation.ObjectAnimator;
import android.animation.TypeEvaluator;
+import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
import android.os.Message;
import android.util.Property;
+import android.util.TypedValue;
+import android.view.Gravity;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.core.content.ContextCompat;
+
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
+import com.google.maps.android.ui.IconGenerator;
+
import java.util.HashMap;
+import java.util.Locale;
+
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollProxy;
import org.appcelerator.kroll.annotations.Kroll;
@@ -30,6 +45,7 @@
import org.appcelerator.titanium.TiPoint;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
+import org.appcelerator.titanium.util.TiUIHelper;
import org.appcelerator.titanium.view.TiDrawableReference;
@Kroll.proxy(creatableInModule = MapModule.class,
@@ -268,6 +284,8 @@ public void processOptions()
handleCustomView(getProperty(MapModule.PROPERTY_CUSTOM_VIEW));
} else if (hasProperty(TiC.PROPERTY_IMAGE)) {
handleImage(getProperty(TiC.PROPERTY_IMAGE));
+ } else if (hasProperty(MapModule.PROPERTY_CUSTOM_ICON)) {
+ handleCustomIcon((HashMap) getProperty(MapModule.PROPERTY_CUSTOM_ICON));
} else if (hasProperty(TiC.PROPERTY_PINCOLOR)) {
markerOptions.icon(
BitmapDescriptorFactory.defaultMarker(TiConvert.toFloat(getProperty(TiC.PROPERTY_PINCOLOR))));
@@ -301,6 +319,40 @@ private void handleCustomView(Object obj)
setIconImageDimensions(-1, -1);
}
+ private void handleCustomIcon(HashMap params) {
+ KrollDict customIcon = new KrollDict(params);
+ Context context = TiApplication.getInstance().getApplicationContext();
+
+ String title = customIcon.getString("title");
+ int tintColor = TiConvert.toColor(customIcon.get("tintColor"), context);
+ int textColor = TiConvert.toColor(customIcon.get("textColor"), context);
+
+ Drawable iconDrawable = ContextCompat.getDrawable(context, R.drawable.pin_waypoint);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ iconDrawable.setTint(tintColor);
+ }
+ IconGenerator mIconGenerator = new IconGenerator(context);
+ mIconGenerator.setBackground(iconDrawable);
+
+ if (title != null) {
+ int pinContentSize = (int) context.getResources().getDimension(R.dimen.pin_width);
+ TextView label = new TextView(context);
+ TiUIHelper.styleText(label, customIcon.getKrollDict(TiC.PROPERTY_FONT));
+
+ label.setTextColor(textColor);
+ label.setGravity(Gravity.CENTER);
+ label.setText(title);
+ label.setLayoutParams(new ViewGroup.LayoutParams(pinContentSize, pinContentSize));
+
+ mIconGenerator.setContentView(label);
+ }
+
+ Bitmap icon = mIconGenerator.makeIcon();
+
+ markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
+ setIconImageDimensions(icon.getWidth(), icon.getHeight());
+ }
+
private void handleImage(Object image)
{
// Image path
@@ -312,6 +364,7 @@ private void handleImage(Object image)
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
setIconImageDimensions(bitmap.getWidth(), bitmap.getHeight());
} catch (Exception e) {
+ Log.e(TAG, e.getMessage());
}
return;
}
@@ -321,8 +374,12 @@ private void handleImage(Object image)
if (image instanceof TiBlob) {
Bitmap bitmap = ((TiBlob) image).getImage();
if (bitmap != null) {
- markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
- setIconImageDimensions(bitmap.getWidth(), bitmap.getHeight());
+ try {
+ markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));
+ setIconImageDimensions(bitmap.getWidth(), bitmap.getHeight());
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ }
return;
}
}
diff --git a/android/src/ti/map/MapModule.java b/android/src/ti/map/MapModule.java
index 08a94bfb..b9bf8244 100644
--- a/android/src/ti/map/MapModule.java
+++ b/android/src/ti/map/MapModule.java
@@ -9,22 +9,39 @@
package ti.map;
import org.appcelerator.kroll.KrollModule;
+import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.annotations.Kroll;
import org.appcelerator.titanium.TiApplication;
+import org.appcelerator.titanium.util.TiConvert;
+import org.appcelerator.titanium.TiC;
+import org.appcelerator.kroll.common.Log;
+
+import android.location.Location;
+import androidx.annotation.NonNull;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
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;
@Kroll.module(name = "Map", id = "ti.map")
-public class MapModule extends KrollModule
+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_READY = "ready";
public static final String EVENT_ON_SNAPSHOT_READY = "onsnapshotready";
public static final String EVENT_REGION_WILL_CHANGE = "regionwillchange";
public static final String EVENT_USER_LOCATION = "userLocation";
+ public static final String EVENT_IDLE = "idle";
public static final String PROPERTY_DRAGGABLE = "draggable";
public static final String PROPERTY_POINTS = "points";
@@ -47,6 +64,8 @@ public class MapModule extends KrollModule
public static final String PROPERTY_PADDING = "padding";
public static final String PROPERTY_TILT = "tilt";
public static final String PROPERTY_BEARING = "bearing";
+
+ public static final String PROPERTY_CUSTOM_ICON = "customIcon";
public static final String PROPERTY_ZOOM = "zoom";
public static final String PROPERTY_ZORDER_ON_TOP = "zOrderOnTop";
public static final String PROPERTY_CENTER_OFFSET = "centerOffset";
@@ -68,7 +87,9 @@ public class MapModule extends KrollModule
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";
@Kroll.constant
public static final int NORMAL_TYPE = GoogleMap.MAP_TYPE_NORMAL;
@@ -135,7 +156,7 @@ public class MapModule extends KrollModule
public MapModule()
{
super();
- MapsInitializer.initialize(TiApplication.getInstance().getApplicationContext());
+ MapsInitializer.initialize(TiApplication.getInstance().getApplicationContext(), MapsInitializer.Renderer.LATEST, this);
}
@Kroll.method
@@ -144,9 +165,51 @@ 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()
{
return "Ti.Map";
}
+
+ @Override
+ public void onMapsSdkInitialized(@NonNull MapsInitializer.Renderer renderer)
+ {
+ switch (renderer) {
+ case LATEST:
+ Log.d("MapsDemo", "The latest version of the renderer is used.");
+ break;
+ case LEGACY:
+ Log.d("MapsDemo", "The legacy version of the renderer is used.");
+ break;
+ }
+ }
}
diff --git a/android/src/ti/map/PolygonProxy.java b/android/src/ti/map/PolygonProxy.java
index 15266074..94672e81 100644
--- a/android/src/ti/map/PolygonProxy.java
+++ b/android/src/ti/map/PolygonProxy.java
@@ -23,6 +23,7 @@
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
+import com.google.maps.android.PolyUtil;
@Kroll.proxy(name = "Polygon", creatableInModule = MapModule.class,
propertyAccessors =
@@ -154,21 +155,29 @@ 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();
- // multiple points
+
+ // 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) {
+ 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 ac3d6095..1d51d1c6 100644
--- a/android/src/ti/map/PolylineProxy.java
+++ b/android/src/ti/map/PolylineProxy.java
@@ -29,15 +29,15 @@
import com.google.android.gms.maps.model.Dot;
import com.google.android.gms.maps.model.Gap;
import com.google.android.gms.maps.model.PatternItem;
+import com.google.maps.android.PolyUtil;
@Kroll.proxy(name = "Polyline", creatableInModule = MapModule.class,
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;
@@ -52,12 +52,14 @@ public class PolylineProxy extends KrollProxy implements IShape
private static final int MSG_SET_ZINDEX = MSG_FIRST_ID + 503;
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_GEODESIC = MSG_FIRST_ID + 506;
public static final String PROPERTY_STROKE_COLOR2 = "color";
public static final String PROPERTY_STROKE_WIDTH2 = "width";
public static final String PROPERTY_STROKE_PATTERN2 = "pattern";
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;
@@ -76,8 +78,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;
@@ -116,6 +118,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);
}
@@ -160,6 +168,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(
@@ -181,21 +193,29 @@ 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();
- //multiple points
+
+ // 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) {
+ for (LatLng point : PolyUtil.decode((String) points)) {
+ addLocation(point, locationArray, list);
+ }
+
return locationArray;
}
- //single point
+ // Single point
addLocation(points, locationArray, list);
return locationArray;
}
@@ -223,7 +243,6 @@ public Polyline getPolyline()
@Override
public void onPropertyChanged(String name, Object value)
{
-
super.onPropertyChanged(name, value);
if (polyline == null) {
@@ -261,7 +280,12 @@ 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));
}
}
@@ -278,7 +302,10 @@ private LatLng parseLocation(Object loc)
} 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;
}
diff --git a/android/src/ti/map/TiUIMapView.java b/android/src/ti/map/TiUIMapView.java
index faf4fe76..59e4349f 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;
@@ -17,15 +16,19 @@
import android.graphics.Point;
import android.location.Location;
import android.os.Build;
+import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
+import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
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.GoogleMapOptions;
+import com.google.android.gms.maps.MapView;
+import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
@@ -33,47 +36,57 @@
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.maps.android.MarkerManager;
+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.collections.MarkerManager;
+
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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.annotations.Kroll;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.titanium.TiApplication;
+import org.appcelerator.titanium.TiBaseActivity;
import org.appcelerator.titanium.TiBlob;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.io.TiFileFactory;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
+import org.appcelerator.titanium.util.TiRHelper;
import org.appcelerator.titanium.view.TiUIFragment;
+import org.appcelerator.titanium.view.TiUIView;
+import org.appcelerator.titanium.TiLifecycle.OnLifecycleEvent;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import ti.map.Shape.Boundary;
import ti.map.Shape.IShape;
-import ti.map.Shape.PolylineBoundary;
-public class TiUIMapView extends TiUIFragment
+public class TiUIMapView extends TiUIView
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";
private static final String TAG = "TiUIMapView";
+ private static final String MAP_FRAGMENT_TAG = "map";
private GoogleMap map;
protected boolean animate = false;
protected boolean preLayout = true;
+ protected boolean liteMode = false;
protected LatLngBounds preLayoutUpdateBounds;
protected ArrayList timarkers;
protected AnnotationProxy selectedAnnotation;
@@ -85,15 +98,69 @@ public class TiUIMapView extends TiUIFragment
private ClusterManager mClusterManager;
private MarkerManager mMarkerManager;
+ private SupportMapFragment mapFragment;
+
+ private MapView mapView;
+
+ public boolean rawMap = false;
+
public TiUIMapView(final TiViewProxy proxy, Activity activity)
{
- super(proxy, activity);
+ super(proxy);
timarkers = new ArrayList();
currentCircles = new ArrayList();
currentPolygons = new ArrayList();
currentPolylines = new ArrayList();
currentImageOverlays = new ArrayList();
proxy.setProperty(MapModule.PROPERTY_INDOOR_ENABLED, true);
+
+ var rawMap = TiConvert.toBoolean(proxy.getProperty("rawMap"), false);
+
+ try {
+ var inflater = activity.getLayoutInflater();
+ var view = inflater.inflate(TiRHelper.getResource(rawMap ? "layout.ti_map_raw" : "layout.ti_map"), null);
+ if (rawMap) {
+ mapView = (MapView) view;
+ }
+ setNativeView(view);
+ } catch (TiRHelper.ResourceNotFoundException e) {
+ Log.d("TiUIMapView", "Failed to load layout for TiUIMapView");
+ }
+
+ if (rawMap) {
+ mapView.onCreate(null);
+ mapView.getMapAsync(this);
+ } else {
+ var sfm = ((AppCompatActivity)activity).getSupportFragmentManager();
+ mapFragment = (SupportMapFragment)sfm.findFragmentByTag(MAP_FRAGMENT_TAG);
+
+ if (mapFragment == null) {
+ // Create a SupportMapFragment with our options
+ var zOrderOnTop = TiConvert.toBoolean(proxy.getProperty(MapModule.PROPERTY_ZORDER_ON_TOP), false);
+ GoogleMapOptions gOptions = new GoogleMapOptions();
+ gOptions.zOrderOnTop(zOrderOnTop);
+ var liteMode = TiConvert.toBoolean(proxy.getProperty(MapModule.PROPERTY_LITE_MODE), false);
+ if (liteMode) {
+ gOptions.liteMode(true);
+ }
+ mapFragment = SupportMapFragment.newInstance(gOptions);
+
+ // Add it using a FragmentTransaction
+ sfm.beginTransaction()
+ .setReorderingAllowed(true)
+ .add(R.id.fragment_container_view, mapFragment, MAP_FRAGMENT_TAG)
+ .commit();
+ }
+
+ mapFragment.getMapAsync(this);
+ }
+ }
+
+ public void initializeMap() {
+ if (mapView != null) {
+ mapView.onCreate(null);
+ mapView.getMapAsync(this);
+ }
}
/**
@@ -118,27 +185,6 @@ private void setBackgroundTransparent(View v)
}
}
- @Override
- protected Fragment createFragment()
- {
- if (proxy == null) {
- Fragment map = SupportMapFragment.newInstance();
- if (map instanceof SupportMapFragment) {
- ((SupportMapFragment) map).getMapAsync(this);
- }
- return map;
- } else {
- boolean zOrderOnTop = TiConvert.toBoolean(proxy.getProperty(MapModule.PROPERTY_ZORDER_ON_TOP), false);
- GoogleMapOptions gOptions = new GoogleMapOptions();
- gOptions.zOrderOnTop(zOrderOnTop);
- Fragment map = SupportMapFragment.newInstance(gOptions);
- if (map instanceof SupportMapFragment) {
- ((SupportMapFragment) map).getMapAsync(this);
- }
- return map;
- }
- }
-
protected void processPreloadRoutes()
{
ArrayList routes = ((ViewProxy) proxy).getPreloadRoutes();
@@ -188,6 +234,8 @@ public void onMapReady(GoogleMap gMap)
return;
}
+ MapsInitializer.initialize(proxy.getActivity().getApplicationContext());
+
//A workaround for https://code.google.com/p/android/issues/detail?id=11676 pre Jelly Bean.
//This problem doesn't exist on 4.1+ since the map base view changes to TextureView from SurfaceView.
if (Build.VERSION.SDK_INT < 16) {
@@ -209,21 +257,29 @@ public void onMapReady(GoogleMap gMap)
processPreloadCircles();
processPreloadPolylines();
processOverlaysList();
+
map.setOnMarkerClickListener(mMarkerManager);
map.setOnMapClickListener(this);
- map.setOnCameraIdleListener(this);
- map.setOnCameraMoveStartedListener(this);
- map.setOnCameraMoveListener(this);
+ if (!this.liteMode) {
+ map.setOnCameraIdleListener(this);
+ map.setOnCameraMoveStartedListener(this);
+ map.setOnCameraMoveListener(this);
+ }
map.setOnMarkerDragListener(this);
map.setOnInfoWindowClickListener(this);
map.setInfoWindowAdapter(this);
map.setOnMapLongClickListener(this);
map.setOnMapLoadedCallback(this);
map.setOnMyLocationChangeListener(this);
+ map.setOnPoiClickListener(this);
+ map.setOnPolylineClickListener(this);
+
mClusterManager.setOnClusterClickListener(this);
mClusterManager.setOnClusterItemClickListener(this);
((ViewProxy) proxy).clearPreloadObjects();
+
+ fireEvent(MapModule.EVENT_READY, new KrollDict());
}
@Override
@@ -239,6 +295,13 @@ public void processProperties(KrollDict d)
public void processMapProperties(KrollDict d)
{
+ if (d.containsKey("rawMap")) {
+ this.rawMap = d.getBoolean("rawMap");
+ this.liteMode = true;
+ }
+ if (d.containsKey(MapModule.PROPERTY_LITE_MODE)) {
+ this.liteMode = d.getBoolean(MapModule.PROPERTY_LITE_MODE);
+ }
if (d.containsKey(TiC.PROPERTY_USER_LOCATION)) {
setUserLocationEnabled(TiConvert.toBoolean(d, TiC.PROPERTY_USER_LOCATION, false));
}
@@ -264,22 +327,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));
}
@@ -298,6 +357,9 @@ public void processMapProperties(KrollDict d)
if (d.containsKey(MapModule.PROPERTY_INDOOR_ENABLED)) {
setIndoorEnabled(d.getBoolean(MapModule.PROPERTY_INDOOR_ENABLED));
}
+ if (d.containsKey(TiC.PROPERTY_PADDING)) {
+ setPadding(d.getKrollDict(TiC.PROPERTY_PADDING));
+ }
}
@Override
@@ -336,6 +398,8 @@ public void propertyChanged(String key, Object oldValue, Object newValue, KrollP
setStyle(TiConvert.toString(newValue, ""));
} else if (key.equals(MapModule.PROPERTY_INDOOR_ENABLED)) {
setIndoorEnabled(TiConvert.toBoolean(newValue, true));
+ } else if (key.equals(TiC.PROPERTY_PADDING)) {
+ setPadding(new KrollDict((HashMap) newValue));
} else {
super.propertyChanged(key, oldValue, newValue, proxy);
}
@@ -379,15 +443,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");
}
}
@@ -400,7 +466,7 @@ protected void setCompassEnabled(boolean enabled)
protected void setIndoorEnabled(boolean enabled)
{
- if (map != null) {
+ if (map != null && !this.liteMode) {
map.setIndoorEnabled(enabled);
}
}
@@ -449,15 +515,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)
@@ -472,15 +543,40 @@ 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);
+
+ if (!this.liteMode && animated) {
+ map.animateCamera(cameraUpdate);
+ } else {
+ map.moveCamera(cameraUpdate);
+ }
- int padding = 30;
- CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
- map.animateCamera(cu);
+ if (this.liteMode) {
+ // Lite mode only supports full integer zoom levels and rounds down (7.4 -> 7)
+ // so we double check that all points are visible and zoom out if necessary
+ for (TiMarker marker : markers) {
+ var markerLocation = marker.getPosition();
+ var currentLatLngBounds = map.getProjection().getVisibleRegion().latLngBounds;
+ if (!currentLatLngBounds.contains(markerLocation)) {
+ map.moveCamera(CameraUpdateFactory.zoomOut());
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ Log.e(TAG, e.getMessage());
+ }
}
protected void setZoomControlsEnabled(boolean enabled)
@@ -492,7 +588,7 @@ protected void setZoomControlsEnabled(boolean enabled)
protected void setScrollEnabled(boolean enabled)
{
- if (map != null) {
+ if (map != null && !this.liteMode) {
map.getUiSettings().setScrollGesturesEnabled(enabled);
}
}
@@ -544,8 +640,11 @@ public void updateCamera(HashMap dict)
CameraPosition.Builder cameraBuilder = new CameraPosition.Builder();
LatLng location = new LatLng(latitude, longitude);
cameraBuilder.target(location);
- cameraBuilder.bearing(bearing);
- cameraBuilder.tilt(tilt);
+ if (!this.liteMode) {
+ // Tilt or bearing are not supported in lite mode
+ cameraBuilder.bearing(bearing);
+ cameraBuilder.tilt(tilt);
+ }
cameraBuilder.zoom(zoom);
if (dict.containsKey(TiC.PROPERTY_LATITUDE_DELTA) && dict.get(TiC.PROPERTY_LATITUDE_DELTA) != null) {
@@ -561,7 +660,7 @@ public void updateCamera(HashMap dict)
LatLng southwest = new LatLng(latitude - (latitudeDelta / 2.0), longitude - (longitudeDelta / 2.0));
final LatLngBounds bounds = new LatLngBounds(southwest, northeast);
- if (preLayout) {
+ if (!this.liteMode && preLayout) {
preLayoutUpdateBounds = bounds;
return;
} else {
@@ -595,7 +694,9 @@ protected void addAnnotation(AnnotationProxy annotation)
TiMarker tiMarker = annotation.getTiMarker();
if (tiMarker != null) {
timarkers.remove(tiMarker);
- tiMarker.getMarker().remove();
+ if (tiMarker.getMarker() != null) {
+ tiMarker.getMarker().remove();
+ }
}
if (map != null) {
@@ -704,7 +805,9 @@ protected void selectAnnotation(Object annotation)
String title = (String) annotation;
TiMarker marker = findMarkerByTitle(title);
if (marker != null) {
- marker.getMarker().showInfoWindow();
+ if (marker.getMarker() != null) {
+ marker.getMarker().showInfoWindow();
+ }
selectedAnnotation = marker.getProxy();
}
}
@@ -721,7 +824,9 @@ protected void deselectAnnotation(Object annotation)
String title = (String) annotation;
TiMarker marker = findMarkerByTitle(title);
if (marker != null) {
- marker.getMarker().hideInfoWindow();
+ if (marker.getMarker() != null) {
+ marker.getMarker().hideInfoWindow();
+ }
}
}
selectedAnnotation = null;
@@ -748,7 +853,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)
@@ -820,8 +931,7 @@ public void addPolyline(PolylineProxy p)
return;
}
p.processOptions();
- p.setPolyline(map.addPolyline(p.getOptions()));
-
+ p.setPolyline( createPolyLine(p.getOptions()) );
currentPolylines.add(p);
}
@@ -931,6 +1041,17 @@ public void changeZoomLevel(int delta)
moveCamera(camUpdate, animate);
}
+ protected boolean containsCoordinate(KrollDict coordinate) {
+ if (map == null) {
+ return false;
+ }
+
+ LatLngBounds mapBounds = map.getProjection().getVisibleRegion().latLngBounds;
+ LatLng nativeCoordinate = new LatLng(coordinate.getDouble("latitude").doubleValue(), coordinate.getDouble("longitude").doubleValue());
+
+ return mapBounds.contains(nativeCoordinate);
+ }
+
public void fireShapeClickEvent(LatLng clickPosition, IShape shapeProxy, String clickSource)
{
@@ -992,6 +1113,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();
@@ -1108,7 +1243,7 @@ public void onMapClick(LatLng point)
clickableCircles.clear();
}
- // currentPolygons
+ // currentPolygons
ArrayList clickablePolygones = new ArrayList();
for (PolygonProxy polygonProxy : currentPolygons) {
if (polygonProxy.getClickable()) {
@@ -1116,7 +1251,6 @@ public void onMapClick(LatLng point)
}
}
if (clickablePolygones.size() > 0) {
-
Boundary boundary = new Boundary();
ArrayList clickedPolygon = boundary.contains(clickablePolygones, point);
boundary = null;
@@ -1129,37 +1263,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);
@@ -1169,6 +1272,12 @@ public void onMapClick(LatLng point)
}
}
+ @Override
+ public void onPoiClick(PointOfInterest poi)
+ {
+ firePOIClickEvent(poi);
+ }
+
@Override
public void onMapLongClick(LatLng point)
{
@@ -1224,10 +1333,12 @@ public void onInfoWindowClick(Marker marker)
@Override
public void onMyLocationChange(Location arg0)
{
- KrollDict d = new KrollDict();
- d.put(TiC.PROPERTY_LATITUDE, arg0.getLatitude());
- d.put(TiC.PROPERTY_LONGITUDE, arg0.getLongitude());
- proxy.fireEvent(MapModule.EVENT_USER_LOCATION, d);
+ if (proxy != null) {
+ KrollDict d = new KrollDict();
+ d.put(TiC.PROPERTY_LATITUDE, arg0.getLatitude());
+ d.put(TiC.PROPERTY_LONGITUDE, arg0.getLongitude());
+ proxy.fireEvent(MapModule.EVENT_USER_LOCATION, d);
+ }
}
@Override
@@ -1305,6 +1416,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));
@@ -1315,15 +1427,16 @@ public void onCameraIdle()
// bounds
proxy.setProperty(TiC.PROPERTY_REGION, d);
proxy.fireEvent(TiC.EVENT_REGION_CHANGED, d);
+ proxy.fireEvent(MapModule.EVENT_IDLE, d);
}
- if (mClusterManager != null) {
+ if (mClusterManager != null && !this.liteMode) {
mClusterManager.onCameraIdle();
}
}
// Intercept the touch event to find out the correct clicksource if clicking
// on the info window.
- @Override
+ // @Override
protected boolean interceptTouchEvent(MotionEvent ev)
{
if (ev.getAction() == MotionEvent.ACTION_UP && selectedAnnotation != null) {
@@ -1396,4 +1509,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 d7bd9bf4..9ecbb889 100644
--- a/android/src/ti/map/ViewProxy.java
+++ b/android/src/ti/map/ViewProxy.java
@@ -9,6 +9,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.annotations.Kroll;
@@ -16,6 +17,7 @@
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiMessenger;
import org.appcelerator.titanium.TiApplication;
+import org.appcelerator.titanium.TiBaseActivity;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
@@ -23,15 +25,27 @@
import ti.map.AnnotationProxy.AnnotationDelegate;
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.model.Dash;
+import com.google.android.gms.maps.model.Gap;
+import com.google.android.gms.maps.model.LatLng;
+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;
+
@Kroll.
proxy(creatableInModule = MapModule.class,
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";
@@ -55,6 +69,7 @@ public class ViewProxy extends TiViewProxy implements AnnotationDelegate
private static final int MSG_SET_PADDING = MSG_FIRST_ID + 514;
private static final int MSG_ZOOM = MSG_FIRST_ID + 515;
private static final int MSG_SHOW_ANNOTATIONS = MSG_FIRST_ID + 516;
+ private static final int MSG_CONTAINS_COORDINATE = MSG_FIRST_ID + 517;
private static final int MSG_ADD_POLYGON = MSG_FIRST_ID + 901;
private static final int MSG_REMOVE_POLYGON = MSG_FIRST_ID + 902;
@@ -310,17 +325,40 @@ public boolean handleMessage(Message msg)
case MSG_SHOW_ANNOTATIONS: {
result = ((AsyncResult) msg.obj);
- handleShowAnnotations((Object[]) result.getArg());
+ handleShowAnnotations((Object[]) result.getArg(), 30, false);
result.setResult(null);
return true;
}
+ case MSG_CONTAINS_COORDINATE: {
+ result = ((AsyncResult) msg.obj);
+ result.setResult(Boolean.valueOf(handleContainsCoordinate((KrollDict)result.getArg())));
+ return true;
+ }
+
default: {
return super.handleMessage(msg);
}
}
}
+ @Kroll.method
+ public void clear() {
+ var view = (TiUIMapView)peekView();
+ if (view.getMap() != null) {
+ view.getMap().clear();
+ view.getMap().setMapType(GoogleMap.MAP_TYPE_NONE);
+ }
+ }
+
+ @Kroll.method
+ public void initializeMap() {
+ var view = (TiUIMapView)peekView();
+ if (view != null) {
+ view.initializeMap();
+ }
+ }
+
@Kroll.method
public void addAnnotation(AnnotationProxy annotation)
{
@@ -416,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;
@@ -434,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);
}
}
@@ -1008,6 +1046,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
*/
@@ -1135,6 +1239,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
@@ -1151,11 +1269,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
@@ -1208,19 +1331,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))) {
@@ -1332,12 +1442,7 @@ 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/Annotation.yml b/apidoc/Annotation.yml
index 196c336e..b6dfe346 100644
--- a/apidoc/Annotation.yml
+++ b/apidoc/Annotation.yml
@@ -65,6 +65,16 @@ properties:
type: Point
platforms: [android, iphone, ipad]
+ - name: customIcon
+ summary: A custom icon that displays a pin and a text above it.
+ description: |
+ It is used to have a natively generated icon without crossing the JavaScript bridge for
+ each icon generation. This is especially important for larger collections of custom icons,
+ as they can be garbage-collected and therefore not be displayed in some cases where memory is low.
+ type: CustomIconParams
+ since: "5.1.0"
+ platforms: [android]
+
- name: customView
summary: Defines a custom view to be used by the annotation.
description: |
@@ -75,7 +85,7 @@ properties:
- name: showAsMarker
summary: |
- Boolean to show an annotation view that displays a balloon-shaped
+ Boolean to show an annotation view that displays a balloon-shaped
marker at the designated location.
description: |
Must be set during creation. This is ignored if the customView property is set.
@@ -89,9 +99,9 @@ properties:
- name: markerGlyphText
summary: The text to display in the marker balloon.
description: |
- Use this property or the property to specify the marker balloon content.
+ Use this property or the property to specify the marker balloon content.
If you specify both an image and text, the text is displayed.
- The amount of space available for displaying your glyph text is limited. Specify no more than
+ The amount of space available for displaying your glyph text is limited. Specify no more than
two or three characters for any strings you assign to this property.
type: String
platforms: [iphone, ipad]
@@ -101,7 +111,7 @@ properties:
- name: markerGlyphColor
summary: The color to apply to the glyph text or image.
description: |
- The default value of this property is undefined, which applies the standard tint color for the
+ The default value of this property is undefined, which applies the standard tint color for the
current map style.
type: String
platforms: [iphone, ipad]
@@ -123,10 +133,10 @@ properties:
description: |
Use this property or the property to specify the marker balloon content.
If you specify both an image and text, the text is displayed.
- The glyph image is displayed when the marker is in the normal state. Create glyph images as template
- images so that the glyph tint color can be applied to it. Normally, you set the size of this image to
- 20 by 20 points on iOS. However, if you do not provide a separate selected image in the
- property, make the size of this image 40 by 40 points on iOS. MapKit scales images that are larger or
+ The glyph image is displayed when the marker is in the normal state. Create glyph images as template
+ images so that the glyph tint color can be applied to it. Normally, you set the size of this image to
+ 20 by 20 points on iOS. However, if you do not provide a separate selected image in the
+ property, make the size of this image 40 by 40 points on iOS. MapKit scales images that are larger or
smaller than those sizes.
type: [String, Titanium.Blob]
platforms: [iphone, ipad]
@@ -136,10 +146,10 @@ properties:
- name: markerSelectedGlyphImage
summary: The image to display when the marker is selected.
description: |
- The glyph image is displayed when the marker is in the selected state. This image is displayed only when the
- marker is selected. If you specify an image for this property, you should also specify an image in the
+ The glyph image is displayed when the marker is in the selected state. This image is displayed only when the
+ marker is selected. If you specify an image for this property, you should also specify an image in the
property.
- Create glyph images as template images so that the glyph tint color can be applied to it. Set the size of this image
+ Create glyph images as template images so that the glyph tint color can be applied to it. Set the size of this image
to 40 by 40 points on iOS. MapKit scales images that are larger or smaller than those sizes.
type: [String, Titanium.Blob]
platforms: [iphone, ipad]
@@ -168,7 +178,7 @@ properties:
- name: markerSubtitleVisibility
summary: The visibility of the subtitle text rendered below the marker balloon.
description: |
- The subtitle text is hidden when the marker is not selected. The text is shown when the marker
+ The subtitle text is hidden when the marker is not selected. The text is shown when the marker
is selected. Use , or .
type: Number
constants: Modules.Map.FEATURE_VISIBILITY_*
@@ -189,9 +199,9 @@ properties:
- name: annotationDisplayPriority
summary: The display priority of this annotation view.
description: |
- An annotation view whose priority is set to MKFeatureDisplayPriorityRequired is always visible
- on the map, whereas other priorities may result in the annotation view being hidden. Use
- , or
+ An annotation view whose priority is set to MKFeatureDisplayPriorityRequired is always visible
+ on the map, whereas other priorities may result in the annotation view being hidden. Use
+ , or
.
type: Number
constants: Modules.Map.FEATURE_DISPLAY_PRIORITY_*
@@ -203,11 +213,11 @@ properties:
- name: clusterIdentifier
summary: An identifier that determines whether the annotation view participates in clustering.
description: |
- The default value of this property is null, which prevents the annotation view from being clustered
+ The default value of this property is null, which prevents the annotation view from being clustered
with other annotation views. Setting the property to a non null value it to participate in clustering.
Clustering occurs when there is a collision between multiple annotation views with the same identifier
- on the map surface. The annotation views involved in the collision are removed from the map view and
- replaced by a clustering annotation view, which displays the title from one of the annotations and
+ on the map surface. The annotation views involved in the collision are removed from the map view and
+ replaced by a clustering annotation view, which displays the title from one of the annotations and
provides access to the other annotations.
type: String
default: null
@@ -241,9 +251,9 @@ properties:
summary: |
The color of the pin-annotation. Use the `ANNOTATION_*` constants for pre-
defined colors, e.g `ANNOTATION_GREEN`.
-
+
Note for iOS: Apps running iOS 9 and later can also specify a non-constant
- value, e.g. "blue", "rgb(0, 0, 255 ,1)" or "#0000ff".
+ value, e.g. "blue", "rgb(0, 0, 255 ,1)" or "#0000ff".
description: |
Pin color is ignored if a custom pin image is specified using .
type: [Number, String]
diff --git a/apidoc/View.yml b/apidoc/View.yml
index 2c413e0f..287daf68 100644
--- a/apidoc/View.yml
+++ b/apidoc/View.yml
@@ -481,6 +481,31 @@ events:
since: "6.2.0"
platforms: [android, iphone, ipad]
+ - 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" }
summary: |
@@ -984,7 +1009,7 @@ since: "3.2.0"
---
name: ClusterAnnotationParams
summary: |
- Simple object used to create cluster annotation view.
+ Simple object used to create a cluster annotation view.
properties:
- name: memberAnnotations
@@ -1001,3 +1026,24 @@ properties:
platforms: [iphone, ipad]
since: "6.3.0"
+
+---
+name: CustomIconParams
+summary: |
+ Simple object used to create a custom marker icon.
+properties:
+
+ - name: title
+ summary: The title of the marker
+ type: String
+
+ - name: textColor
+ summary: The text color of the marker
+ type: String
+
+ - name: tintColor
+ summary: The tint color of the marker
+ type: String
+
+platforms: [android]
+since: "5.1.0"
\ No newline at end of file
diff --git a/ios/Classes/TiMapAnnotationProxy.h b/ios/Classes/TiMapAnnotationProxy.h
index 2b385abb..f0640f22 100644
--- a/ios/Classes/TiMapAnnotationProxy.h
+++ b/ios/Classes/TiMapAnnotationProxy.h
@@ -5,8 +5,7 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
-#import "TiViewProxy.h"
+#import
#import
@class TiMapViewProxy;
@@ -34,7 +33,6 @@
- (NSString *)subtitle;
- (id)pincolor;
-- (id)nativePinColor;
- (BOOL)animatesDrop;
- (void)setHidden:(id)value;
diff --git a/ios/Classes/TiMapAnnotationProxy.m b/ios/Classes/TiMapAnnotationProxy.m
index acc860f4..e18bfbdc 100644
--- a/ios/Classes/TiMapAnnotationProxy.m
+++ b/ios/Classes/TiMapAnnotationProxy.m
@@ -6,14 +6,11 @@
*/
#import "TiMapAnnotationProxy.h"
-#import "ImageLoader.h"
#import "TiButtonUtil.h"
#import "TiMapConstants.h"
#import "TiMapView.h"
#import "TiMapViewProxy.h"
#import "TiUIiOSPreviewContextProxy.h"
-#import "TiUtils.h"
-#import "TiViewProxy.h"
#import "UIColor+AndroidHueParity.h"
@implementation TiMapAnnotationProxy
@@ -223,7 +220,7 @@ - (id)hidden
- (id)pincolor
{
- return NUMINT([self valueForUndefinedKey:@"pincolor"]);
+ return NUMINT((int)[self valueForUndefinedKey:@"pincolor"]);
}
- (void)setPincolor:(id)color
@@ -235,67 +232,6 @@ - (void)setPincolor:(id)color
}
}
-// Mapping both string-colors, color constant and native colors to a pin color
-// This is overcomplicated to maintain iOS < 9 compatibility. Remove this when
-// we have a minimum iOS verion of 9.0+
-- (id)nativePinColor
-{
- id current = [self valueForUndefinedKey:@"pincolor"];
-
- if ([current isKindOfClass:[NSString class]]) {
-#ifdef __IPHONE_9_0
- return [[TiUtils colorValue:current] color];
-#else
- return MKPinAnnotationColorRed;
-#endif
- }
-
- switch ([TiUtils intValue:current def:TiMapAnnotationPinColorRed]) {
- case TiMapAnnotationPinColorGreen: {
-#ifdef __IPHONE_9_0
- return [MKPinAnnotationView greenPinColor];
-#else
- return MKPinAnnotationColorGreen;
-#endif
- }
- case TiMapAnnotationPinColorPurple: {
-#ifdef __IPHONE_9_0
- return [MKPinAnnotationView purplePinColor];
-#else
- return MKPinAnnotationColorPurple;
-#endif
- }
-#ifdef __IPHONE_9_0
- case TiMapAnnotationPinColorBlue:
- return [UIColor blueColor];
- case TiMapAnnotationPinColorCyan:
- return [UIColor cyanColor];
- case TiMapAnnotationPinColorMagenta:
- return [UIColor magentaColor];
- case TiMapAnnotationPinColorOrange:
- return [UIColor orangeColor];
- case TiMapAnnotationPinColorYellow:
- return [UIColor yellowColor];
-
- // UIColor extensions
- case TiMapAnnotationPinColorAzure:
- return [UIColor azureColor];
- case TiMapAnnotationPinColorRose:
- return [UIColor roseColor];
- case TiMapAnnotationPinColorViolet:
- return [UIColor violetColor];
-#endif
- case TiMapAnnotationPinColorRed:
- default: {
-#ifdef __IPHONE_9_0
- return [MKPinAnnotationView redPinColor];
-#else
- return MKPinAnnotationColorRed;
-#endif
- }
- }
-}
-
- (BOOL)animatesDrop
{
return [TiUtils boolValue:[self valueForUndefinedKey:@"animate"]];
@@ -365,6 +301,8 @@ - (void)setLeftView:(id)leftview
}
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wundeclared-selector"
- (void)setPreviewContext:(id)previewContext
{
Class TiUIiOSPreviewContextProxy = NSClassFromString(@"TiUIiOSPreviewContextProxy");
@@ -393,6 +331,7 @@ - (void)setPreviewContext:(id)previewContext
[self setNeedsRefreshingWithSelection:YES];
}
}
+#pragma clang diagnostic pop
- (void)setImage:(id)image
{
@@ -502,7 +441,6 @@ - (void)setAnnotationDisplayPriority:(id)displayPriority
}
}
-#if IS_IOS_11
- (void)setClusterIdentifier:(id)clusterIdentifier
{
id current = [self valueForUndefinedKey:@"clusterIdentifier"];
@@ -511,7 +449,6 @@ - (void)setClusterIdentifier:(id)clusterIdentifier
[self setNeedsRefreshingWithSelection:YES];
}
}
-#endif
- (void)setCustomView:(id)customView
{
diff --git a/ios/Classes/TiMapCameraProxy.h b/ios/Classes/TiMapCameraProxy.h
index 3a5b3526..95eaf8dc 100644
--- a/ios/Classes/TiMapCameraProxy.h
+++ b/ios/Classes/TiMapCameraProxy.h
@@ -5,7 +5,7 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiProxy.h"
+#import
#import
@interface TiMapCameraProxy : TiProxy {
diff --git a/ios/Classes/TiMapCameraProxy.m b/ios/Classes/TiMapCameraProxy.m
index be119926..d448609b 100644
--- a/ios/Classes/TiMapCameraProxy.m
+++ b/ios/Classes/TiMapCameraProxy.m
@@ -6,7 +6,7 @@
*/
#import "TiMapCameraProxy.h"
-#import "TiUtils.h"
+#import
@implementation TiMapCameraProxy
diff --git a/ios/Classes/TiMapCircleProxy.h b/ios/Classes/TiMapCircleProxy.h
index 8f3662f0..e83e2768 100644
--- a/ios/Classes/TiMapCircleProxy.h
+++ b/ios/Classes/TiMapCircleProxy.h
@@ -8,8 +8,7 @@
#ifndef map_TiMapCircleProxy_h
#define map_TiMapCircleProxy_h
-#import "TiBase.h"
-#import "TiViewProxy.h"
+#import
#import
@class TiMapViewProxy;
diff --git a/ios/Classes/TiMapCircleProxy.m b/ios/Classes/TiMapCircleProxy.m
index bffe2b38..f0563e7b 100644
--- a/ios/Classes/TiMapCircleProxy.m
+++ b/ios/Classes/TiMapCircleProxy.m
@@ -86,7 +86,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];
}
@@ -96,7 +96,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/TiMapCustomAnnotationView.h b/ios/Classes/TiMapCustomAnnotationView.h
index 29b68b08..8cfaefde 100644
--- a/ios/Classes/TiMapCustomAnnotationView.h
+++ b/ios/Classes/TiMapCustomAnnotationView.h
@@ -5,10 +5,9 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
-#import "TiMapView.h"
-#import "TiViewProxy.h"
+#import
#import
+#import "TiMapView.h"
@interface TiMapCustomAnnotationView : MKAnnotationView {
@private
diff --git a/ios/Classes/TiMapCustomAnnotationView.m b/ios/Classes/TiMapCustomAnnotationView.m
index 6a21dfa8..feed14af 100644
--- a/ios/Classes/TiMapCustomAnnotationView.m
+++ b/ios/Classes/TiMapCustomAnnotationView.m
@@ -6,7 +6,6 @@
*/
#import "TiMapCustomAnnotationView.h"
-#import "TiBase.h"
@implementation TiMapCustomAnnotationView
@@ -15,7 +14,7 @@ - (id)initWithAnnotation:(id)annotation reuseIdentifier:(NSString
if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
self.backgroundColor = [UIColor clearColor];
wrapperView = [[UIView alloc] initWithFrame:CGRectZero];
- wrapperView.userInteractionEnabled = false;
+ wrapperView.userInteractionEnabled = NO;
[self addSubview:wrapperView];
}
return self;
diff --git a/ios/Classes/TiMapImageAnnotationView.h b/ios/Classes/TiMapImageAnnotationView.h
index feacb934..0844c4a7 100644
--- a/ios/Classes/TiMapImageAnnotationView.h
+++ b/ios/Classes/TiMapImageAnnotationView.h
@@ -5,9 +5,9 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
-#import "TiMapView.h"
+#import
#import
+#import "TiMapView.h"
@interface TiMapImageAnnotationView : MKAnnotationView {
@private
diff --git a/ios/Classes/TiMapImageAnnotationView.m b/ios/Classes/TiMapImageAnnotationView.m
index e032c723..b08b9199 100644
--- a/ios/Classes/TiMapImageAnnotationView.m
+++ b/ios/Classes/TiMapImageAnnotationView.m
@@ -6,7 +6,6 @@
*/
#import "TiMapImageAnnotationView.h"
-#import "TiBase.h"
@implementation TiMapImageAnnotationView
diff --git a/ios/Classes/TiMapImageOverlayProxy.h b/ios/Classes/TiMapImageOverlayProxy.h
index 0d979486..16714edf 100644
--- a/ios/Classes/TiMapImageOverlayProxy.h
+++ b/ios/Classes/TiMapImageOverlayProxy.h
@@ -6,7 +6,7 @@
*/
#import "TiMapImageOverlayRenderer.h"
-#import "TiProxy.h"
+#import
@interface TiMapImageOverlay : NSObject
diff --git a/ios/Classes/TiMapImageOverlayProxy.m b/ios/Classes/TiMapImageOverlayProxy.m
index e2d5fe6d..a70fd88f 100644
--- a/ios/Classes/TiMapImageOverlayProxy.m
+++ b/ios/Classes/TiMapImageOverlayProxy.m
@@ -6,7 +6,6 @@
*/
#import "TiMapImageOverlayProxy.h"
-#import "TiUtils.h"
@implementation TiMapImageOverlay
@synthesize coordinate, boundingMapRect;
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/TiMapImageOverlayRenderer.m b/ios/Classes/TiMapImageOverlayRenderer.m
index fb9f3756..c21662f1 100644
--- a/ios/Classes/TiMapImageOverlayRenderer.m
+++ b/ios/Classes/TiMapImageOverlayRenderer.m
@@ -6,7 +6,6 @@
*/
#import "TiMapImageOverlayRenderer.h"
-#import "TiBase.h"
@interface TiMapImageOverlayRenderer ()
diff --git a/ios/Classes/TiMapMarkerAnnotationView.h b/ios/Classes/TiMapMarkerAnnotationView.h
index 79961cf9..9a45c144 100644
--- a/ios/Classes/TiMapMarkerAnnotationView.h
+++ b/ios/Classes/TiMapMarkerAnnotationView.h
@@ -4,10 +4,9 @@
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
-#if IS_IOS_11
-#import "TiBase.h"
-#import "TiMapView.h"
+#import
#import
+#import "TiMapView.h"
@interface TiMapMarkerAnnotationView : MKMarkerAnnotationView {
@private
@@ -18,4 +17,3 @@
- (NSString *)lastHitName;
@end
-#endif
diff --git a/ios/Classes/TiMapMarkerAnnotationView.m b/ios/Classes/TiMapMarkerAnnotationView.m
index 1b51e8a3..fd27b006 100644
--- a/ios/Classes/TiMapMarkerAnnotationView.m
+++ b/ios/Classes/TiMapMarkerAnnotationView.m
@@ -4,7 +4,6 @@
* Licensed under the terms of the Apache Public License
* Please see the LICENSE included with this distribution for details.
*/
-#if IS_IOS_11
#import "TiMapMarkerAnnotationView.h"
#import "TiMapView.h"
@@ -63,4 +62,3 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
return result;
}
@end
-#endif
diff --git a/ios/Classes/TiMapModule.h b/ios/Classes/TiMapModule.h
index 6e1aa5ac..c66b4a1c 100644
--- a/ios/Classes/TiMapModule.h
+++ b/ios/Classes/TiMapModule.h
@@ -5,25 +5,19 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiModule.h"
+#import
@interface TiMapModule : TiModule {
UIColor *colorRed;
}
-+ (void)logAddedIniOS7Warning:(NSString *)name;
-
@property (nonatomic, readonly) NSNumber *STANDARD_TYPE;
@property (nonatomic, readonly) NSNumber *NORMAL_TYPE; // For parity with Android
@property (nonatomic, readonly) NSNumber *SATELLITE_TYPE;
@property (nonatomic, readonly) NSNumber *HYBRID_TYPE;
-#ifdef __IPHONE_9_0
@property (nonatomic, readonly) NSNumber *HYBRID_FLYOVER_TYPE;
@property (nonatomic, readonly) NSNumber *SATELLITE_FLYOVER_TYPE;
-#endif
-#if IS_IOS_11
@property (nonatomic, readonly) NSNumber *MUTED_STANDARD_TYPE;
-#endif
@property (nonatomic, readonly) NSNumber *ANNOTATION_RED;
@property (nonatomic, readonly) NSNumber *ANNOTATION_GREEN;
diff --git a/ios/Classes/TiMapModule.m b/ios/Classes/TiMapModule.m
index a0da72cc..703b70ab 100644
--- a/ios/Classes/TiMapModule.m
+++ b/ios/Classes/TiMapModule.m
@@ -32,13 +32,6 @@ - (NSString *)apiName
return @"Ti.Map";
}
-#pragma mark Utils
-
-+ (void)logAddedIniOS7Warning:(NSString *)name
-{
- NSLog(@"[WARN] `%@` is only supported on iOS 7 and greater.", name);
-}
-
#pragma mark Public APIs
- (TiMapViewProxy *)createView:(id)args
@@ -48,10 +41,6 @@ - (TiMapViewProxy *)createView:(id)args
- (TiMapCameraProxy *)createCamera:(id)args
{
- if (![TiUtils isIOS7OrGreater]) {
- [TiMapModule logAddedIniOS7Warning:@"createCamera()"];
- return nil;
- }
return [[[TiMapCameraProxy alloc] _initWithPageContext:[self pageContext] args:args] autorelease];
}
@@ -59,17 +48,12 @@ - (TiMapCameraProxy *)createCamera:(id)args
MAKE_SYSTEM_PROP(NORMAL_TYPE, MKMapTypeStandard); // For parity with Android
MAKE_SYSTEM_PROP(SATELLITE_TYPE, MKMapTypeSatellite);
MAKE_SYSTEM_PROP(HYBRID_TYPE, MKMapTypeHybrid);
-#ifdef __IPHONE_9_0
MAKE_SYSTEM_PROP(HYBRID_FLYOVER_TYPE, MKMapTypeHybridFlyover);
MAKE_SYSTEM_PROP(SATELLITE_FLYOVER_TYPE, MKMapTypeSatelliteFlyover);
-#endif
-#if IS_IOS_11
MAKE_SYSTEM_PROP(MUTED_STANDARD_TYPE, MKMapTypeMutedStandard);
-#endif
MAKE_SYSTEM_PROP(ANNOTATION_RED, TiMapAnnotationPinColorRed);
MAKE_SYSTEM_PROP(ANNOTATION_GREEN, TiMapAnnotationPinColorGreen);
MAKE_SYSTEM_PROP(ANNOTATION_PURPLE, TiMapAnnotationPinColorPurple);
-#ifdef __IPHONE_9_0
MAKE_SYSTEM_PROP(ANNOTATION_AZURE, TiMapAnnotationPinColorAzure);
MAKE_SYSTEM_PROP(ANNOTATION_BLUE, TiMapAnnotationPinColorBlue);
MAKE_SYSTEM_PROP(ANNOTATION_CYAN, TiMapAnnotationPinColorCyan);
@@ -78,7 +62,6 @@ - (TiMapCameraProxy *)createCamera:(id)args
MAKE_SYSTEM_PROP(ANNOTATION_ROSE, TiMapAnnotationPinColorRose);
MAKE_SYSTEM_PROP(ANNOTATION_VIOLET, TiMapAnnotationPinColorViolet);
MAKE_SYSTEM_PROP(ANNOTATION_YELLOW, TiMapAnnotationPinColorYellow);
-#endif
MAKE_SYSTEM_PROP(ANNOTATION_DRAG_STATE_NONE, MKAnnotationViewDragStateNone);
MAKE_SYSTEM_PROP(ANNOTATION_DRAG_STATE_START, MKAnnotationViewDragStateStarting);
@@ -92,7 +75,6 @@ - (TiMapCameraProxy *)createCamera:(id)args
MAKE_SYSTEM_PROP(POLYLINE_PATTERN_DASHED, TiMapOverlyPatternTypeDashed);
MAKE_SYSTEM_PROP(POLYLINE_PATTERN_DOTTED, TiMapOverlyPatternTypeDotted);
-#if IS_IOS_11
MAKE_SYSTEM_PROP(FEATURE_VISIBILITY_ADAPTIVE, MKFeatureVisibilityAdaptive);
MAKE_SYSTEM_PROP(FEATURE_VISIBILITY_HIDDEN, MKFeatureVisibilityHidden);
MAKE_SYSTEM_PROP(FEATURE_VISIBILITY_VISIBLE, MKFeatureVisibilityVisible);
@@ -103,6 +85,5 @@ - (TiMapCameraProxy *)createCamera:(id)args
MAKE_SYSTEM_PROP_DBL(FEATURE_DISPLAY_PRIORITY_REQUIRED, MKFeatureDisplayPriorityRequired);
MAKE_SYSTEM_PROP_DBL(FEATURE_DISPLAY_PRIORITY_DEFAULT_HIGH, MKFeatureDisplayPriorityDefaultHigh);
MAKE_SYSTEM_PROP_DBL(FEATURE_DISPLAY_PRIORITY_DEFAULT_LOW, MKFeatureDisplayPriorityDefaultLow);
-#endif
@end
diff --git a/ios/Classes/TiMapPinAnnotationView.h b/ios/Classes/TiMapPinAnnotationView.h
index 7411cb52..35741778 100644
--- a/ios/Classes/TiMapPinAnnotationView.h
+++ b/ios/Classes/TiMapPinAnnotationView.h
@@ -5,11 +5,11 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
-#import "TiMapView.h"
+#import
#import
+#import "TiMapView.h"
-@interface TiMapPinAnnotationView : MKPinAnnotationView {
+@interface TiMapPinAnnotationView : MKMarkerAnnotationView {
@private
NSString *lastHitName;
diff --git a/ios/Classes/TiMapPolygonProxy.h b/ios/Classes/TiMapPolygonProxy.h
index 96866a55..2b0ca720 100644
--- a/ios/Classes/TiMapPolygonProxy.h
+++ b/ios/Classes/TiMapPolygonProxy.h
@@ -5,8 +5,7 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
-#import "TiViewProxy.h"
+#import
#import
@class TiMapViewProxy;
diff --git a/ios/Classes/TiMapPolygonProxy.m b/ios/Classes/TiMapPolygonProxy.m
index b9e64c98..0cd5be6a 100644
--- a/ios/Classes/TiMapPolygonProxy.m
+++ b/ios/Classes/TiMapPolygonProxy.m
@@ -101,6 +101,9 @@ - (CLLocationCoordinate2D)processLocation:(id)locObj
lat = [TiUtils doubleValue:[locObj objectAtIndex:1]];
lon = [TiUtils doubleValue:[locObj objectAtIndex:0]];
coord = CLLocationCoordinate2DMake(lat, lon);
+ } else {
+ [self throwException:@"Invalid coordinate tyoe" subreason:@"Use either a dictionary or array" location:CODELOCATION];
+ coord = CLLocationCoordinate2DMake(0.0, 0.0);
}
return coord;
@@ -143,7 +146,7 @@ - (void)setFillColor:(id)value
if (fillColor != nil) {
RELEASE_TO_NIL(fillColor);
}
- fillColor = [[TiColor colorNamed:value] retain];
+ fillColor = [[TiUtils colorValue:value] retain];
[self applyFillColor];
}
@@ -152,7 +155,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 a641524f..d8f68b18 100644
--- a/ios/Classes/TiMapPolylineProxy.h
+++ b/ios/Classes/TiMapPolylineProxy.h
@@ -5,14 +5,9 @@
* Please see the LICENSE included with this distribution for details.
*/
-#ifndef map_TiMapPolylineProxy_h
-#define map_TiMapPolylineProxy_h
-
-#import "TiBase.h"
-#import "TiMapOverlayPattern.h"
-#import "TiViewProxy.h"
-
+#import
#import
+#import "TiMapOverlayPattern.h"
@class TiMapViewProxy;
@@ -29,5 +24,3 @@
@property (nonatomic, readonly) MKPolylineRenderer *polylineRenderer;
@end
-
-#endif
diff --git a/ios/Classes/TiMapPolylineProxy.m b/ios/Classes/TiMapPolylineProxy.m
index 389323b3..dcd178b4 100644
--- a/ios/Classes/TiMapPolylineProxy.m
+++ b/ios/Classes/TiMapPolylineProxy.m
@@ -76,7 +76,11 @@ - (CLLocationCoordinate2D)processLocation:(id)locObj
lat = [TiUtils doubleValue:[locObj objectAtIndex:1]];
lon = [TiUtils doubleValue:[locObj objectAtIndex:0]];
coord = CLLocationCoordinate2DMake(lat, lon);
+ } else {
+ [self throwException:@"Invalid coordinate tyoe" subreason:@"Use either a dictionary or array" location:CODELOCATION];
+ coord = CLLocationCoordinate2DMake(0.0, 0.0);
}
+
return coord;
}
@@ -129,7 +133,7 @@ - (void)setStrokeColor:(id)value
if (strokeColor != nil) {
RELEASE_TO_NIL(strokeColor);
}
- strokeColor = [[[TiColor colorNamed:value] _color] retain];
+ strokeColor = [[[TiUtils colorValue:value] _color] retain];
[self applyStrokeColor];
}
diff --git a/ios/Classes/TiMapRouteProxy.h b/ios/Classes/TiMapRouteProxy.h
index 04250a8e..d952739b 100644
--- a/ios/Classes/TiMapRouteProxy.h
+++ b/ios/Classes/TiMapRouteProxy.h
@@ -6,8 +6,7 @@
*/
#import "TiMKOverlayPathUniversal.h"
-#import "TiProxy.h"
-#import "TiUtils.h"
+#import
#import
@interface TiMapRouteProxy : TiProxy {
diff --git a/ios/Classes/TiMapRouteProxy.m b/ios/Classes/TiMapRouteProxy.m
index cb53170b..00acba0e 100644
--- a/ios/Classes/TiMapRouteProxy.m
+++ b/ios/Classes/TiMapRouteProxy.m
@@ -6,9 +6,7 @@
*/
#import "TiMapRouteProxy.h"
-#import "TiBase.h"
#import "TiMapModule.h"
-#import "TiUtils.h"
@implementation TiMapRouteProxy
@@ -65,11 +63,7 @@ - (void)processPoints:(NSArray *)points
routeLine = [[MKPolyline polylineWithPoints:pointArray count:[points count]] retain];
free(pointArray);
- // Using the TiMKOverlayPathUniversal protocol so Xcode can resolve methods
- // MKPolylineView is deprecated in iOS 7, still here for backward compatibility.
- // MKPolylineView can be removed when support is dropped for iOS 6 and below.
- Class rendererClass = ([TiUtils isIOS7OrGreater]) ? [MKPolylineRenderer class] : [MKPolylineView class];
- routeRenderer = [(id)[[rendererClass alloc] initWithPolyline:routeLine] retain];
+ routeRenderer = [(id)[[MKPolylineRenderer alloc] initWithPolyline:routeLine] retain];
[self applyColor];
[self applyWidth];
}
@@ -105,7 +99,7 @@ - (void)setColor:(id)value
if (color != nil) {
RELEASE_TO_NIL(color);
}
- color = [[TiColor colorNamed:value] retain];
+ color = [[TiUtils colorValue:value] retain];
[self applyColor];
}
@@ -117,10 +111,6 @@ - (void)setWidth:(id)value
- (void)setLevel:(id)value
{
- // level is not supported before iOS 7 but it doesn't hurt to capture it.
- if (![TiUtils isIOS7OrGreater]) {
- [TiMapModule logAddedIniOS7Warning:@"level"];
- }
level = [[TiUtils numberFromObject:value] unsignedIntegerValue];
}
diff --git a/ios/Classes/TiMapSnapshotterProxy.h b/ios/Classes/TiMapSnapshotterProxy.h
index e4ba0947..38cc3173 100644
--- a/ios/Classes/TiMapSnapshotterProxy.h
+++ b/ios/Classes/TiMapSnapshotterProxy.h
@@ -5,7 +5,7 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiProxy.h"
+#import
#import
@interface TiMapSnapshotterProxy : TiProxy {
diff --git a/ios/Classes/TiMapSnapshotterProxy.m b/ios/Classes/TiMapSnapshotterProxy.m
index 3674a3be..d559232b 100644
--- a/ios/Classes/TiMapSnapshotterProxy.m
+++ b/ios/Classes/TiMapSnapshotterProxy.m
@@ -92,12 +92,12 @@ - (void)takeSnapshot:(id)args
return;
}
- TiBlob *blob = [[[TiBlob alloc] _initWithPageContext:[self pageContext]] autorelease];
- [blob setImage:[snapshot image]];
+ TiBlob *blob = [[TiBlob alloc] initWithImage:snapshot.image];
[blob setMimeType:@"image/png" type:TiBlobTypeImage];
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 599c1386..965f1465 100644
--- a/ios/Classes/TiMapView.h
+++ b/ios/Classes/TiMapView.h
@@ -5,12 +5,11 @@
* Please see the LICENSE included with this distribution for details.
*/
-#import "TiBase.h"
+#import
+#import
#import "TiMKOverlayPathUniversal.h"
#import "TiMapCameraProxy.h"
-#import "TiUIView.h"
#import "WildcardGestureRecognizer.h"
-#import
@class TiMapAnnotationProxy;
@@ -32,10 +31,8 @@
NSMutableArray *circleProxies;
NSMutableArray *polylineProxies;
NSMutableArray *imageOverlayProxies;
-
-#if IS_IOS_11
NSMutableDictionary *clusterAnnotations;
-#endif
+
//selected annotation
MKAnnotationView *selectedAnnotation;
@@ -93,11 +90,10 @@
- (void)addImageOverlays:(id)args;
- (void)removeImageOverlay:(id)arg;
- (void)removeAllImageOverlays;
+- (NSNumber *)containsCoordinate:(id)coordinate;
- (void)firePinChangeDragState:(MKAnnotationView *)pinview newState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState;
-#if IS_IOS_11
- (void)setClusterAnnotation:(TiMapAnnotationProxy *)annotation forMembers:(NSArray *)members;
-#endif
#pragma mark Utils
- (void)addOverlay:(MKPolyline *)polyline level:(MKOverlayLevel)level;
diff --git a/ios/Classes/TiMapView.m b/ios/Classes/TiMapView.m
index 06497ffa..95bb730d 100644
--- a/ios/Classes/TiMapView.m
+++ b/ios/Classes/TiMapView.m
@@ -43,9 +43,8 @@ - (void)dealloc
RELEASE_TO_NIL(polylineProxies);
RELEASE_TO_NIL(circleProxies);
RELEASE_TO_NIL(imageOverlayProxies);
-#if IS_IOS_11
RELEASE_TO_NIL(clusterAnnotations);
-#endif
+
[super dealloc];
}
@@ -79,9 +78,6 @@ - (MKMapView *)map
map.delegate = self;
map.userInteractionEnabled = YES;
map.autoresizingMask = UIViewAutoresizingNone;
- if (![TiUtils isIOS8OrGreater]) {
- map.showsUserLocation = [TiUtils boolValue:[self.proxy valueForKey:@"userLocation"] def:NO];
- }
[self addSubview:map];
mapObjects2View = CFDictionaryCreateMutable(NULL, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
[self registerTouchEvents];
@@ -194,7 +190,7 @@ - (NSArray *)annotationsFromArgs:(id)value
- (void)refreshAnnotation:(TiMapAnnotationProxy *)proxy readd:(BOOL)yn
{
NSArray *selected = map.selectedAnnotations;
- BOOL wasSelected = [selected containsObject:proxy]; //If selected == nil, this still returns FALSE.
+ BOOL wasSelected = [selected containsObject:proxy]; //If selected == nil, this still returns NO.
ignoreClicks = YES;
if (yn == NO) {
[map deselectAnnotation:proxy animated:NO];
@@ -470,26 +466,19 @@ - (void)setUserLocation_:(id)value
// Release the locationManager in case it was already created
RELEASE_TO_NIL(locationManager);
- BOOL userLocation = [TiUtils boolValue:value def:NO];
- // if userLocation is true and this is iOS 8 or greater, then ask for permission
- if (userLocation && [TiUtils isIOS8OrGreater]) {
- // the locationManager needs to be created to permissions
- locationManager = [[CLLocationManager alloc] init];
- // set the "userLocation" on the delegate callback to avoid console warnings from the OS
- locationManager.delegate = self;
- if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]) {
- [locationManager requestAlwaysAuthorization];
- } else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
- [locationManager requestWhenInUseAuthorization];
- } else {
- NSLog(@"[ERROR] The keys NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription are not defined in your tiapp.xml. Starting with iOS 8 this is required.");
- }
- // Create the map
- [self map];
+ // the locationManager needs to be created to permissions
+ locationManager = [[CLLocationManager alloc] init];
+ // set the "userLocation" on the delegate callback to avoid console warnings from the OS
+ locationManager.delegate = self;
+ if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]) {
+ [locationManager requestAlwaysAuthorization];
+ } else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
+ [locationManager requestWhenInUseAuthorization];
} else {
- // else, just apply the userLocation
- [self map].showsUserLocation = userLocation;
+ NSLog(@"[ERROR] The keys NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription are not defined in your tiapp.xml. Starting with iOS 8 this is required.");
}
+ // Create the map
+ [self map];
}
- (void)setLocation_:(id)location
@@ -809,44 +798,26 @@ - (void)setShowsCompass_:(id)value
- (void)setCompassEnabled_:(id)value
{
- if ([TiUtils isIOS9OrGreater] == YES) {
-#ifdef __IPHONE_9_0
- TiThreadPerformOnMainThread(^{
- [[self map] setShowsCompass:[TiUtils boolValue:value]];
- },
- YES);
-#endif
- } else {
- NSLog(@"[WARN] The property 'compassEnabled' is only available on iOS 9 and later.");
- }
+ TiThreadPerformOnMainThread(^{
+ [[self map] setShowsCompass:[TiUtils boolValue:value]];
+ },
+ YES);
}
- (void)setShowsScale_:(id)value
{
- if ([TiUtils isIOS9OrGreater] == YES) {
-#ifdef __IPHONE_9_0
- TiThreadPerformOnMainThread(^{
- [self map].showsScale = [TiUtils boolValue:value];
- },
- YES);
-#endif
- } else {
- NSLog(@"[WARN] The property 'showsScale' is only available on iOS 9 and later.");
- }
+ TiThreadPerformOnMainThread(^{
+ [self map].showsScale = [TiUtils boolValue:value];
+ },
+ YES);
}
- (void)setShowsTraffic_:(id)value
{
- if ([TiUtils isIOS9OrGreater] == YES) {
-#ifdef __IPHONE_9_0
- TiThreadPerformOnMainThread(^{
- [self map].showsTraffic = [TiUtils boolValue:value];
- },
- YES);
-#endif
- } else {
- NSLog(@"[WARN] The property 'showsTraffic' is only available on iOS 9 and later.");
- }
+ TiThreadPerformOnMainThread(^{
+ [self map].showsTraffic = [TiUtils boolValue:value];
+ },
+ YES);
}
- (void)showAllAnnotations:(id)value
@@ -911,7 +882,6 @@ - (void)showAnnotations:(id)args
NO);
}
-#if IS_IOS_11
- (void)setClusterAnnotation:(TiMapAnnotationProxy *)annotation forMembers:(NSArray *)members
{
if (!clusterAnnotations) {
@@ -930,7 +900,6 @@ - (TiMapAnnotationProxy *)clusterAnnotationProxyForMembers:(NSArray *)members
{
return [clusterAnnotations objectForKey:members];
}
-#endif
#pragma mark Utils
@@ -1051,8 +1020,8 @@ - (void)firePinChangeDragState:(MKAnnotationView *)pinview newState:(MKAnnotatio
ourProxy, @"map",
title, @"title",
[NSNumber numberWithInteger:[pinview tag]], @"index",
- NUMINT(newState), @"newState",
- NUMINT(oldState), @"oldState",
+ NUMINTEGER(newState), @"newState",
+ NUMINTEGER(oldState), @"oldState",
nil];
if (parentWants)
@@ -1083,7 +1052,7 @@ - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *
selectedAnnotation = [ann retain];
- // If canShowCallout == true we will try to find calloutView to hadleTap on callout
+ // If canShowCallout is YES we will try to find calloutView to hadleTap on callout
if ([ann canShowCallout]) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void) {
[self findCalloutView:ann];
@@ -1110,22 +1079,20 @@ - (void)findCalloutView:(UIView *)node
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if ([view conformsToProtocol:@protocol(TiMapAnnotation)]) {
- BOOL isSelected = [TiUtils boolValue:[view isSelected] def:NO];
MKAnnotationView *ann = (MKAnnotationView *)view;
if (selectedAnnotation == ann) {
RELEASE_TO_NIL(ann);
}
- // TODO: Fire a deselected event for the annotation?
- [self fireClickEvent:view source:isSelected ? @"pin" : @"map" deselected:YES];
+ [self fireClickEvent:view source:view.isSelected ? @"pin" : @"map" deselected:YES];
}
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)aview calloutAccessoryControlTapped:(UIControl *)control
{
if ([aview conformsToProtocol:@protocol(TiMapAnnotation)]) {
- MKPinAnnotationView *pinview = (MKPinAnnotationView *)aview;
+ MKMarkerAnnotationView *pinview = (MKMarkerAnnotationView *)aview;
NSString *clickSource = @"unknown";
if (aview.leftCalloutAccessoryView == control) {
clickSource = @"leftButton";
@@ -1150,11 +1117,9 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap
if (customView == nil && !marker) {
id imagePath = [ann valueForUndefinedKey:@"image"];
image = [TiUtils image:imagePath proxy:ann];
- identifier = (image != nil) ? @"timap-image" : @"timap-pin";
+ identifier = (image != nil) ? @"timap-image" : @"timap-marker";
} else if (customView) {
identifier = @"timap-customView";
- } else {
- identifier = @"timap-marker";
}
MKAnnotationView *annView = nil;
annView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
@@ -1162,22 +1127,17 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap
if (annView == nil) {
if ([identifier isEqualToString:@"timap-customView"]) {
annView = [[[TiMapCustomAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:identifier map:self] autorelease];
-#if IS_IOS_11
- } else if ([TiMapView isiOS11OrGreater] && [identifier isEqualToString:@"timap-marker"]) {
- annView = [[[TiMapMarkerAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:identifier map:self] autorelease];
-#endif
} else if ([identifier isEqualToString:@"timap-image"]) {
annView = [[[TiMapImageAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:identifier map:self image:image] autorelease];
} else {
- annView = [[[TiMapPinAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:identifier map:self] autorelease];
+ annView = [[[TiMapMarkerAnnotationView alloc] initWithAnnotation:ann reuseIdentifier:identifier map:self] autorelease];
}
}
if ([identifier isEqualToString:@"timap-customView"]) {
[((TiMapCustomAnnotationView *)annView) setProxy:customView];
} else if ([identifier isEqualToString:@"timap-image"]) {
annView.image = image;
-#if IS_IOS_11
- } else if ([TiMapView isiOS11OrGreater] && [identifier isEqualToString:@"timap-marker"]) {
+ } else {
MKMarkerAnnotationView *markerView = (MKMarkerAnnotationView *)annView;
markerView.markerTintColor = [[TiUtils colorValue:[ann valueForUndefinedKey:@"markerColor"]] color];
markerView.glyphText = [ann valueForUndefinedKey:@"markerGlyphText"];
@@ -1187,29 +1147,17 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap
markerView.selectedGlyphImage = [TiUtils image:[ann valueForUndefinedKey:@"markerSelectedGlyphImage"] proxy:ann];
markerView.titleVisibility = [TiUtils intValue:[ann valueForUndefinedKey:@"markerTitleVisibility"]];
markerView.subtitleVisibility = [TiUtils intValue:[ann valueForUndefinedKey:@"markerSubtitleVisibility"]];
-#endif
- } else {
- MKPinAnnotationView *pinview = (MKPinAnnotationView *)annView;
-
-#ifdef __IPHONE_9_0
- pinview.pinTintColor = [ann nativePinColor];
-#else
- pinview.pinColor = [ann nativePinColor];
-#endif
- pinview.animatesDrop = [ann animatesDrop] && ![ann placed];
- annView.calloutOffset = CGPointMake(-8, 0);
}
+
annView.canShowCallout = [TiUtils boolValue:[ann valueForUndefinedKey:@"canShowCallout"] def:YES];
annView.enabled = YES;
annView.centerOffset = ann.offset;
-#if IS_IOS_11
if ([TiMapView isiOS11OrGreater]) {
annView.clusteringIdentifier = [ann valueForUndefinedKey:@"clusterIdentifier"];
annView.collisionMode = [TiUtils intValue:[ann valueForUndefinedKey:@"collisionMode"]];
annView.displayPriority = [TiUtils floatValue:[ann valueForUndefinedKey:@"annotationDisplayPriority"] def:1000];
}
-#endif
UIView *left = [ann leftViewAccessory];
UIView *right = [ann rightViewAccessory];
@@ -1218,27 +1166,18 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap
if (left != nil) {
annView.leftCalloutAccessoryView = left;
- } else {
- //ios7 requires this to be explicitly set as nil if nil
- if (![TiUtils isIOS8OrGreater]) {
- annView.leftCalloutAccessoryView = nil;
- }
}
if (right != nil) {
annView.rightCalloutAccessoryView = right;
- } else {
- //ios7 requires this to be explicitly set as nil if nil
-
- if (![TiUtils isIOS8OrGreater]) {
- annView.rightCalloutAccessoryView = nil;
- }
}
[annView setDraggable:[TiUtils boolValue:[ann valueForUndefinedKey:@"draggable"]]];
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];
@@ -1251,12 +1190,11 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotationProxy:(TiMap
return nil;
}
-#ifndef __clang_analyzer__
// We can ignore this, as it's guarded above
id previewingDelegate = [[TiPreviewingDelegate alloc] performSelector:@selector(initWithPreviewContext:) withObject:previewContext];
ann.controllerPreviewing = [controller registerForPreviewingWithDelegate:previewingDelegate sourceView:annView];
-#endif
}
+#pragma clang diagnostic pop
return annView;
}
@@ -1269,7 +1207,6 @@ - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id> *)memberAnnotations
{
MKClusterAnnotation *annotation = [[MKClusterAnnotation alloc] initWithMemberAnnotations:memberAnnotations];
@@ -1295,9 +1230,9 @@ - (MKClusterAnnotation *)mapView:(MKMapView *)mapView clusterAnnotationForMember
if ([mapProxy _hasListeners:@"clusterstart"]) {
[mapProxy fireEvent:@"clusterstart" withObject:event];
}
- return annotation;
+
+ return [annotation autorelease];
}
-#endif
// mapView:didAddAnnotationViews: is called after the annotation views have been added and positioned in the map.
// The delegate can implement this method to animate the adding of the annotations views.
@@ -1318,7 +1253,7 @@ - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
thisView.frame = CGRectMake(viewFrame.origin.x, viewFrame.origin.y - self.frame.size.height, viewFrame.size.width, viewFrame.size.height);
[UIView animateWithDuration:0.4
delay:0.0
- options:UIViewAnimationCurveEaseOut
+ options:UIViewAnimationOptionCurveEaseOut
animations:^{
thisView.frame = viewFrame;
}
@@ -1354,6 +1289,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
@@ -1501,12 +1448,7 @@ - (void)fireShapeClickEvent:(id)sourceProxy point:(MKMapPoint)point sourceType:(
- (void)doClickEvent:(id)viewProxy mapProxy:(id)mapProxy event:(NSDictionary *)event
{
BOOL parentWants = [mapProxy _hasListeners:@"click"];
- BOOL viewWants;
- if ([viewProxy respondsToSelector:@selector(_hasListeners)]) {
- viewWants = [viewProxy _hasListeners:@"click"];
- } else {
- viewWants = FALSE;
- }
+ BOOL viewWants = [viewProxy _hasListeners:@"click"];
if (parentWants) {
[mapProxy fireEvent:@"click" withObject:event];
diff --git a/ios/Classes/TiMapViewProxy.h b/ios/Classes/TiMapViewProxy.h
index 66a4ba0e..060aa579 100644
--- a/ios/Classes/TiMapViewProxy.h
+++ b/ios/Classes/TiMapViewProxy.h
@@ -5,12 +5,12 @@
* Please see the LICENSE included with this distribution for details.
*/
+#import
#import "TiMapAnnotationProxy.h"
#import "TiMapCameraProxy.h"
#import "TiMapCircleProxy.h"
#import "TiMapPolygonProxy.h"
#import "TiMapPolylineProxy.h"
-#import "TiViewProxy.h"
@interface TiMapViewProxy : TiViewProxy {
TiMapAnnotationProxy *selectedAnnotation; // Annotation to select on initial display
@@ -64,8 +64,7 @@
- (void)addImageOverlays:(id)args;
- (void)removeImageOverlay:(id)arg;
- (void)removeAllImageOverlays:(id)args;
-
-#if IS_IOS_11
- (void)setClusterAnnotation:(id)args;
-#endif
+- (NSNumber *)containsCoordinate:(id)coordinate;
+
@end
diff --git a/ios/Classes/TiMapViewProxy.m b/ios/Classes/TiMapViewProxy.m
index 44a8d25a..c94ca361 100644
--- a/ios/Classes/TiMapViewProxy.m
+++ b/ios/Classes/TiMapViewProxy.m
@@ -169,6 +169,11 @@ - (TiMapAnnotationProxy *)annotationFromArg:(id)arg
#pragma mark Public API
+- (NSNumber *)mapType
+{
+ return @(((TiMapView *)[self view]).map.mapType);
+}
+
- (void)zoom:(id)arg
{
ENSURE_SINGLE_ARG(arg, NSObject);
@@ -821,7 +826,6 @@ - (void)setImageOverlays:(id)args
}
}
-#if IS_IOS_11
- (void)setClusterAnnotation:(id)args
{
ENSURE_DICT(args);
@@ -834,9 +838,8 @@ - (void)setClusterAnnotation:(id)args
[(TiMapView *)[self view] setClusterAnnotation:annotationProxy forMembers:memberAnnotations];
}
}
-#endif
-#pragma mark Public APIs iOS 7
+#pragma mark Public API's
- (TiMapCameraProxy *)camera
{
@@ -869,4 +872,9 @@ - (void)showAnnotations:(id)args
NO);
}
+- (NSNumber *)containsCoordinate:(id)coordinate
+{
+ return [(TiMapView *)[self view] containsCoordinate:coordinate];
+}
+
@end
diff --git a/ios/TiMap_Prefix.pch b/ios/TiMap_Prefix.pch
index b2bc9956..8bec24fa 100644
--- a/ios/TiMap_Prefix.pch
+++ b/ios/TiMap_Prefix.pch
@@ -2,9 +2,3 @@
#ifdef __OBJC__
#import
#endif
-
-#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
-#define IS_IOS_11 true
-#else
-#define IS_IOS_11 false
-#endif
diff --git a/ios/build.py b/ios/build.py
deleted file mode 100755
index 4b4c1727..00000000
--- a/ios/build.py
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env python
-#
-# Appcelerator Titanium Module Packager
-#
-#
-import os, subprocess, sys, glob, string
-import zipfile
-from datetime import date
-
-cwd = os.path.abspath(os.path.dirname(sys._getframe(0).f_code.co_filename))
-os.chdir(cwd)
-required_module_keys = ['name','version','moduleid','description','copyright','license','copyright','platform','minsdk']
-module_defaults = {
- 'description':'My module',
- 'author': 'Your Name',
- 'license' : 'Specify your license',
- 'copyright' : 'Copyright (c) %s by Your Company' % str(date.today().year),
-}
-module_license_default = "TODO: place your license here and we'll include it in the module distribution"
-
-def find_sdk(config):
- sdk = config['TITANIUM_SDK']
- return os.path.expandvars(os.path.expanduser(sdk))
-
-def replace_vars(config,token):
- idx = token.find('$(')
- while idx != -1:
- idx2 = token.find(')',idx+2)
- if idx2 == -1: break
- key = token[idx+2:idx2]
- if not config.has_key(key): break
- token = token.replace('$(%s)' % key, config[key])
- idx = token.find('$(')
- return token
-
-
-def read_ti_xcconfig():
- contents = open(os.path.join(cwd,'titanium.xcconfig')).read()
- config = {}
- for line in contents.splitlines(False):
- line = line.strip()
- if line[0:2]=='//': continue
- idx = line.find('=')
- if idx > 0:
- key = line[0:idx].strip()
- value = line[idx+1:].strip()
- config[key] = replace_vars(config,value)
- return config
-
-def generate_doc(config):
- docdir = os.path.join(cwd,'documentation')
- if not os.path.exists(docdir):
- print "Couldn't find documentation file at: %s" % docdir
- return None
-
- try:
- import markdown2 as markdown
- except ImportError:
- import markdown
- documentation = []
- for file in os.listdir(docdir):
- if file in ignoreFiles or os.path.isdir(os.path.join(docdir, file)):
- continue
- md = open(os.path.join(docdir,file)).read()
- html = markdown.markdown(md)
- documentation.append({file:html});
- return documentation
-
-def compile_js(manifest,config):
- js_file = os.path.join(cwd,'assets','ti.map.js')
- if not os.path.exists(js_file): return
-
- from compiler import Compiler
- try:
- import json
- except:
- import simplejson as json
-
- compiler = Compiler(cwd, manifest['moduleid'], manifest['name'], 'commonjs')
- root_asset, module_assets = compiler.compile_module()
-
- root_asset_content = """
-%s
-
- return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[0]);
-""" % root_asset
-
- module_asset_content = """
-%s
-
- NSNumber *index = [map objectForKey:path];
- if (index == nil) {
- return nil;
- }
- return filterDataInRange([NSData dataWithBytesNoCopy:data length:sizeof(data) freeWhenDone:NO], ranges[index.integerValue]);
-""" % module_assets
-
- from tools import splice_code
-
- assets_router = os.path.join(cwd,'Classes','TiMapModuleAssets.m')
- splice_code(assets_router, 'asset', root_asset_content)
- splice_code(assets_router, 'resolve_asset', module_asset_content)
-
- # Generate the exports after crawling all of the available JS source
- exports = open('metadata.json','w')
- json.dump({'exports':compiler.exports }, exports)
- exports.close()
-
-def die(msg):
- print msg
- sys.exit(1)
-
-def warn(msg):
- print "[WARN] %s" % msg
-
-def validate_license():
- c = open(os.path.join(cwd,'LICENSE')).read()
- if c.find(module_license_default)!=-1:
- warn('please update the LICENSE file with your license text before distributing')
-
-def validate_manifest():
- path = os.path.join(cwd,'manifest')
- f = open(path)
- if not os.path.exists(path): die("missing %s" % path)
- manifest = {}
- for line in f.readlines():
- line = line.strip()
- if line[0:1]=='#': continue
- if line.find(':') < 0: continue
- key,value = line.split(':')
- manifest[key.strip()]=value.strip()
- for key in required_module_keys:
- if not manifest.has_key(key): die("missing required manifest key '%s'" % key)
- if module_defaults.has_key(key):
- defvalue = module_defaults[key]
- curvalue = manifest[key]
- if curvalue==defvalue: warn("please update the manifest key: '%s' to a non-default value" % key)
- return manifest,path
-
-ignoreFiles = ['.DS_Store','.gitignore','libTitanium.a','titanium.jar','README']
-ignoreDirs = ['.DS_Store','.svn','.git','CVSROOT']
-
-def zip_dir(zf,dir,basepath,ignoreExt=[]):
- if not os.path.exists(dir): return
- for root, dirs, files in os.walk(dir):
- for name in ignoreDirs:
- if name in dirs:
- dirs.remove(name) # don't visit ignored directories
- for file in files:
- if file in ignoreFiles: continue
- e = os.path.splitext(file)
- if len(e) == 2 and e[1] in ignoreExt: continue
- from_ = os.path.join(root, file)
- to_ = from_.replace(dir, '%s/%s'%(basepath,dir), 1)
- zf.write(from_, to_)
-
-def glob_libfiles():
- files = []
- for libfile in glob.glob('build/**/*.a'):
- if libfile.find('Release-')!=-1:
- files.append(libfile)
- return files
-
-def build_module(manifest,config):
- from tools import ensure_dev_path
- ensure_dev_path()
-
- rc = os.system("xcodebuild -sdk iphoneos -configuration Release OTHER_CFLAGS=\"-fembed-bitcode\" CLANG_ENABLE_MODULE_DEBUGGING=NO GCC_PRECOMPILE_PREFIX_HEADER=NO DEBUG_INFORMATION_FORMAT=\"DWARF with dSYM\"")
- if rc != 0:
- die("xcodebuild failed")
- rc = os.system("xcodebuild -sdk iphonesimulator -configuration Release OTHER_CFLAGS=\"-fembed-bitcode\" CLANG_ENABLE_MODULE_DEBUGGING=NO GCC_PRECOMPILE_PREFIX_HEADER=NO DEBUG_INFORMATION_FORMAT=\"DWARF with dSYM\"")
- if rc != 0:
- die("xcodebuild failed")
- # build the merged library using lipo
- moduleid = manifest['moduleid']
- libpaths = ''
- for libfile in glob_libfiles():
- libpaths+='%s ' % libfile
-
- os.system("lipo %s -create -output build/lib%s.a" %(libpaths,moduleid))
-
-def package_module(manifest,mf,config):
- name = manifest['name'].lower()
- moduleid = manifest['moduleid'].lower()
- version = manifest['version']
- modulezip = '%s-iphone-%s.zip' % (moduleid,version)
- if os.path.exists(modulezip): os.remove(modulezip)
- zf = zipfile.ZipFile(modulezip, 'w', zipfile.ZIP_DEFLATED)
- modulepath = 'modules/iphone/%s/%s' % (moduleid,version)
- zf.write(mf,'%s/manifest' % modulepath)
- libname = 'lib%s.a' % moduleid
- zf.write('build/%s' % libname, '%s/%s' % (modulepath,libname))
- docs = generate_doc(config)
- if docs!=None:
- for doc in docs:
- for file, html in doc.iteritems():
- filename = string.replace(file,'.md','.html')
- zf.writestr('%s/documentation/%s'%(modulepath,filename),html)
- zip_dir(zf,'assets',modulepath,['.pyc','.js'])
- zip_dir(zf,'example',modulepath,['.pyc'])
- zip_dir(zf,'platform',modulepath,['.pyc','.js'])
- zf.write('LICENSE','%s/LICENSE' % modulepath)
- zf.write('module.xcconfig','%s/module.xcconfig' % modulepath)
- exports_file = 'metadata.json'
- if os.path.exists(exports_file):
- zf.write(exports_file, '%s/%s' % (modulepath, exports_file))
- zf.close()
-
-
-if __name__ == '__main__':
- manifest,mf = validate_manifest()
- validate_license()
- config = read_ti_xcconfig()
-
- sdk = find_sdk(config)
- sys.path.insert(0,os.path.join(sdk,'iphone'))
- sys.path.append(os.path.join(sdk, "common"))
-
- compile_js(manifest,config)
- build_module(manifest,config)
- package_module(manifest,mf,config)
- sys.exit(0)
-
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.
diff --git a/ios/manifest b/ios/manifest
index 60fd80d6..80f4a7a2 100644
--- a/ios/manifest
+++ b/ios/manifest
@@ -2,7 +2,7 @@
# this is your module manifest and used by Titanium
# during compilation, packaging, distribution, etc.
#
-version: 3.3.1
+version: 4.0.0
apiversion: 2
architectures: armv7 arm64 i386 x86_64
description: External version of Map module
@@ -15,4 +15,4 @@ name: map
moduleid: ti.map
guid: f0d8fd44-86d2-4730-b67d-bd454577aeee
platform: iphone
-minsdk: 6.2.2.GA
+minsdk: 8.0.0
diff --git a/ios/map.xcodeproj/project.pbxproj b/ios/map.xcodeproj/project.pbxproj
index 9123bef4..20aad79d 100644
--- a/ios/map.xcodeproj/project.pbxproj
+++ b/ios/map.xcodeproj/project.pbxproj
@@ -378,17 +378,18 @@
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0600;
+ LastUpgradeCheck = 1100;
};
buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "map" */;
compatibilityVersion = "Xcode 3.2";
- developmentRegion = English;
+ developmentRegion = en;
hasScannedForEncodings = 1;
knownRegions = (
- English,
- Japanese,
- French,
- German,
+ en,
+ Base,
+ fr,
+ ja,
+ de,
);
mainGroup = 0867D691FE84028FC02AAC07 /* map */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
@@ -462,6 +463,7 @@
baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DSTROOT = /tmp/TiMap.dst;
@@ -502,6 +504,7 @@
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
DSTROOT = /tmp/TiMap.dst;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_MODEL_TUNING = G5;
@@ -519,7 +522,7 @@
GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = NO;
INSTALL_PATH = /usr/local/lib;
- IPHONEOS_DEPLOYMENT_TARGET = 6.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LIBRARY_SEARCH_PATHS = "";
OTHER_CFLAGS = "-DTI_POST_1_2";
OTHER_LDFLAGS = "-ObjC";
@@ -534,28 +537,54 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
buildSettings = {
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = NO;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = NO;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = NO;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = NO;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DSTROOT = /tmp/TiMap.dst;
ENABLE_BITCODE = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = c99;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = TiMap_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_VERSION = "";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = NO;
GCC_WARN_MISSING_PARENTHESES = NO;
GCC_WARN_SHADOW = NO;
GCC_WARN_STRICT_SELECTOR_MATCH = NO;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_PARAMETER = NO;
GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = NO;
INSTALL_PATH = /usr/local/lib;
- IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = (
"-DDEBUG",
@@ -568,6 +597,7 @@
RUN_CLANG_STATIC_ANALYZER = NO;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "";
+ USE_HEADERMAP = YES;
};
name = Debug;
};
@@ -576,32 +606,58 @@
baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = NO;
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = NO;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = NO;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = NO;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
DSTROOT = /tmp/TiMap.dst;
ENABLE_BITCODE = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = c99;
GCC_MODEL_TUNING = G5;
+ GCC_NO_COMMON_BLOCKS = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = TiMap_Prefix.pch;
GCC_PREPROCESSOR_DEFINITIONS = "TI_VERSION=$(TI_VERSION)";
GCC_TREAT_WARNINGS_AS_ERRORS = NO;
GCC_VERSION = "";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = NO;
GCC_WARN_MISSING_PARENTHESES = NO;
GCC_WARN_SHADOW = NO;
GCC_WARN_STRICT_SELECTOR_MATCH = NO;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_PARAMETER = NO;
GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = NO;
INSTALL_PATH = /usr/local/lib;
- IPHONEOS_DEPLOYMENT_TARGET = 7.1;
+ IPHONEOS_DEPLOYMENT_TARGET = 9.0;
OTHER_CFLAGS = "-DTI_POST_1_2";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = TiMap;
RUN_CLANG_STATIC_ANALYZER = NO;
SDKROOT = iphoneos;
USER_HEADER_SEARCH_PATHS = "";
+ USE_HEADERMAP = YES;
};
name = Release;
};
@@ -609,6 +665,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
@@ -620,9 +677,9 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 24DD6D1B1134B66800162E58 /* titanium.xcconfig */;
buildSettings = {
+ CLANG_ENABLE_OBJC_WEAK = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = "Build & test";
ZERO_LINK = NO;
};
diff --git a/ios/titanium.xcconfig b/ios/titanium.xcconfig
index da1fa9f1..346259b2 100644
--- a/ios/titanium.xcconfig
+++ b/ios/titanium.xcconfig
@@ -4,7 +4,7 @@
// OF YOUR TITANIUM SDK YOU'RE BUILDING FOR
//
//
-TITANIUM_SDK_VERSION = 9.0.0.GA
+TITANIUM_SDK_VERSION = 9.0.2.GA
//
// THESE SHOULD BE OK GENERALLY AS-IS