diff --git a/LICENSE.md b/LICENSE.md
deleted file mode 100644
index 0750b10..0000000
--- a/LICENSE.md
+++ /dev/null
@@ -1,55 +0,0 @@
-react-native-mapbox-gl copyright (c) 2015, Mapbox.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-===========================================================================
-
-Mapbox GL uses portions of the Mapbox iOS SDK, which was derived from the
-Route-Me open source project, including the Alpstein fork of it.
-
-The Route-Me license appears below.
-
-Copyright (c) 2008-2013, Route-Me Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
diff --git a/RCTMapboxGL/Settings.bundle/en.lproj/Root.strings b/RCTMapboxGL/Settings.bundle/en.lproj/Root.strings
deleted file mode 100644
index 51959f6..0000000
Binary files a/RCTMapboxGL/Settings.bundle/en.lproj/Root.strings and /dev/null differ
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 0000000..e7d178b
--- /dev/null
+++ b/android/build.gradle
@@ -0,0 +1,37 @@
+buildscript {
+ repositories {
+ jcenter()
+ }
+
+ dependencies {
+ classpath 'com.android.tools.build:gradle:1.1.3'
+ }
+}
+
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 23
+ buildToolsVersion "23.0.1"
+
+ defaultConfig {
+ minSdkVersion 16
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ }
+ lintOptions {
+ abortOnError false
+ }
+}
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ compile 'com.facebook.react:react-native:0.11.+'
+ compile('com.mapbox.mapboxsdk:mapbox-android-sdk:2.0.0@aar') {
+ transitive = true
+ }
+}
diff --git a/android/example.js b/android/example.js
new file mode 100644
index 0000000..a428a46
--- /dev/null
+++ b/android/example.js
@@ -0,0 +1,89 @@
+'use strict';
+
+var React = require('react-native');
+var Mapbox = require('react-native-mapbox-gl');
+var {
+ AppRegistry,
+ StyleSheet,
+ View
+} = React;
+
+var MapExample = React.createClass({
+ getInitialState() {
+ return {
+ center: {
+ latitude: 40.7223,
+ longitude: -73.9878
+ },
+ annotations: [{
+ coordinates: [40.7223, -73.9878],
+ type: 'point',
+ title: 'Important!',
+ subtitle: 'Neat, this is a custom annotation image',
+ annotationImage: {
+ url: 'https://cldup.com/7NLZklp8zS.png',
+ height: 25,
+ width: 25
+ },
+ id: 'marker2'
+ }, {
+ coordinates: [40.7923, -73.9178],
+ type: 'point',
+ title: 'Important!',
+ subtitle: 'Neat, this is a custom annotation image',
+ annotationImage: {
+ url: 'https://cldup.com/7NLZklp8zS.png',
+ height: 25,
+ width: 25
+ },
+ id: 'marker2'
+ }, {
+ "coordinates": [[40.76572150042782,-73.99429321289062],[40.743485405490695, -74.00218963623047],[40.728266950429735,-74.00218963623047],[40.728266950429735,-73.99154663085938],[40.73633186448861,-73.98983001708984],[40.74465591168391,-73.98914337158203],[40.749337730454826,-73.9870834350586]],
+ "type": "polyline",
+ "strokeColor": "#00FB00",
+ "strokeWidth": 3,
+ "alpha": 0.5,
+ "id": "foobar"
+ }, {
+ "coordinates": [[40.749857912194386, -73.96820068359375], [40.741924698522055,-73.9735221862793], [40.735681504432264,-73.97523880004883], [40.7315190495212,-73.97438049316406], [40.729177554196376,-73.97180557250975], [40.72345355209305,-73.97438049316406], [40.719290332250544,-73.97455215454102], [40.71369559554873,-73.97729873657227], [40.71200407096382,-73.97850036621094], [40.71031250340588,-73.98691177368163], [40.71031250340588,-73.99154663085938]],
+ "type": "polygon",
+ "alpha":1,
+ "fillColor": "#FFFFFF", // http://developer.android.com/reference/android/graphics/Color.html#parseColor%28java.lang.String%29
+ "strokeColor": "#FFFFFF",
+ "strokeWidth": 1,
+ "id": "zap"
+ }]
+ }
+ },
+ render: function() {
+ return (
+
+
+
+ );
+ }
+});
+
+var styles = StyleSheet.create({
+ container: {
+ flex: 1
+ },
+ map: {
+ width: require('Dimensions').get('window').width,
+ flex: 1
+ }
+});
+
+AppRegistry.registerComponent('your-app-name', () => MapExample);
diff --git a/android/readme.md b/android/readme.md
new file mode 100644
index 0000000..dcfa7a2
--- /dev/null
+++ b/android/readme.md
@@ -0,0 +1,59 @@
+#### Step 1 - NPM Install
+
+```shell
+npm install --save react-native-mapbox-gl
+```
+#### Step 2 - Update Gradle Settings
+
+```gradle
+// file: android/settings.gradle
+...
+
+include ':reactnativemapboxgl', ':app'
+project(':reactnativemapboxgl').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mapbox-gl/android')
+```
+
+#### Step 3 - Update app Gradle Build
+
+```gradle
+// file: android/app/build.gradle
+...
+
+dependencies {
+ ...
+ compile project(':reactnativemapboxgl')
+}
+```
+
+#### Step 4 - Register React Package
+
+```java
+...
+import com.mapbox.reactnativemapboxgl.ReactNativeMapboxGLPackage; // <-- import
+
+public class MainActivity extends FragmentActivity implements DefaultHardwareBackBtnHandler {
+
+ private ReactInstanceManager mReactInstanceManager;
+ private ReactRootView mReactRootView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mReactRootView = new ReactRootView(this);
+ mReactInstanceManager = ReactInstanceManager.builder()
+ .setApplication(getApplication())
+ .setBundleAssetName("index.android.bundle")
+ .setJSMainModuleName("index.android")
+ .addPackage(new MainReactPackage())
+ .addPackage(new ReactNativeMapboxGLPackage()) // <-- Register package here
+ .setUseDeveloperSupport(BuildConfig.DEBUG)
+ .setInitialLifecycleState(LifecycleState.RESUMED)
+ .build();
+ mReactRootView.startReactApplication(mReactInstanceManager, "AwesomeProject", null);
+ setContentView(mReactRootView);
+ }
+...
+
+```
+
+#### Step 5 - Add to project, [see example](/example.js)
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..7959dbd
--- /dev/null
+++ b/android/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
\ No newline at end of file
diff --git a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java
new file mode 100644
index 0000000..e8037da
--- /dev/null
+++ b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLManager.java
@@ -0,0 +1,158 @@
+package com.mapbox.reactnativemapboxgl;
+
+
+import android.graphics.Color;
+import android.util.Log;
+
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.uimanager.BaseViewPropertyApplicator;
+import com.facebook.react.uimanager.CatalystStylesDiffMap;
+import com.facebook.react.uimanager.SimpleViewManager;
+import com.facebook.react.uimanager.ThemedReactContext;
+import com.facebook.react.uimanager.UIProp;
+import com.facebook.react.uimanager.ViewManager;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
+import com.mapbox.mapboxsdk.annotations.PolygonOptions;
+import com.mapbox.mapboxsdk.annotations.PolylineOptions;
+import com.mapbox.mapboxsdk.views.MapView;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.facebook.react.bridge.ReactMethod;
+import com.facebook.react.bridge.ReadableMap;
+import android.graphics.Color;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Objects;
+import java.util.List;
+
+public class ReactNativeMapboxGLManager extends SimpleViewManager {
+ public static final String REACT_CLASS = "RCTMapbox";
+
+ @UIProp(UIProp.Type.STRING)
+ public static final String PROP_ACCESS_TOKEN = "accessToken";
+ @UIProp(UIProp.Type.ARRAY)
+ public static final String PROP_ANNOTATIONS = "annotations";
+ @UIProp(UIProp.Type.MAP)
+ public static final String PROP_CENTER_COORDINATE = "centerCoordinate";
+ @UIProp(UIProp.Type.BOOLEAN)
+ public static final String PROP_DEBUG_ACTIVE = "debugActive";
+ @UIProp(UIProp.Type.NUMBER)
+ public static final String PROP_DIRECTION = "direction";
+ @UIProp(UIProp.Type.BOOLEAN)
+ public static final String PROP_ROTATION_ENABLED = "rotationEnabled";
+ @UIProp(UIProp.Type.STRING)
+ public static final String PROP_SCROLL_ENABLED = "scrollEnabled";
+ @UIProp(UIProp.Type.STRING)
+ public static final String PROP_STYLE_URL = "styleUrl";
+ @UIProp(UIProp.Type.BOOLEAN)
+ public static final String PROP_ZOOM_ENABLED = "zoomEnabled";
+ @UIProp(UIProp.Type.NUMBER)
+ public static final String PROP_ZOOM_LEVEL = "zoomLevel";
+
+ @Override
+ public String getName() {
+ return REACT_CLASS;
+ }
+
+ @Override
+ public MapView createViewInstance(ThemedReactContext context) {
+ MapView mv = new MapView(context);
+ mv.setAccessToken("pk.eyJ1IjoiYm9iYnlzdWQiLCJhIjoiTi16MElIUSJ9.Clrqck--7WmHeqqvtFdYig");
+ mv.setStyleUrl("asset://styles/dark-v8.json");
+ mv.onCreate(null);
+ mv.onStart();
+ return mv;
+ }
+
+ @Override
+ public void updateView(final MapView view,
+ final CatalystStylesDiffMap props) {
+
+ BaseViewPropertyApplicator.applyCommonViewProperties(view, props);
+ if (props.hasKey(PROP_ACCESS_TOKEN)) {
+ view.setAccessToken(props.getString(PROP_ACCESS_TOKEN));
+ }
+ if (props.hasKey(PROP_ANNOTATIONS)) {
+ int size = props.getArray(PROP_ANNOTATIONS).size();
+ for (int i = 0; i < size; i++) {
+ ReadableMap annotation = props.getArray(PROP_ANNOTATIONS).getMap(i);
+ String type = annotation.getString("type");
+ if (type.equals("point")) {
+ double latitude = annotation.getArray("coordinates").getDouble(0);
+ double longitude = annotation.getArray("coordinates").getDouble(1);
+ String title = annotation.getString("title");
+ String subtitle = annotation.getString("title");
+ LatLng markerCenter = new LatLng(latitude, longitude);
+ MarkerOptions marker = new MarkerOptions();
+ marker.position(markerCenter);
+ marker.title(title);
+ marker.snippet(subtitle);
+ marker.isDraggable();
+ view.addMarker(marker);
+ } else if (type.equals("polyline")) {
+ int coordSize = annotation.getArray("coordinates").size();
+ PolylineOptions polyline = new PolylineOptions();
+ for (int p = 0; p < coordSize; p++) {
+ double latitude = annotation.getArray("coordinates").getArray(p).getDouble(0);
+ double longitude = annotation.getArray("coordinates").getArray(p).getDouble(1);
+ polyline.add(new LatLng(latitude, longitude));
+ }
+ double strokeAlpha = annotation.getDouble("alpha");
+ int strokeColor = Color.parseColor(annotation.getString("strokeColor"));
+ float strokeWidth = annotation.getInt("strokeWidth");
+ polyline.alpha((float) strokeAlpha);
+ polyline.color(strokeColor);
+ polyline.width(strokeWidth);
+ view.addPolyline(polyline);
+ } else if (type.equals("polygon")) {
+ int coordSize = annotation.getArray("coordinates").size();
+ PolygonOptions polygon = new PolygonOptions();
+ for (int p = 0; p < coordSize; p++) {
+ double latitude = annotation.getArray("coordinates").getArray(p).getDouble(0);
+ double longitude = annotation.getArray("coordinates").getArray(p).getDouble(1);
+ polygon.add(new LatLng(latitude, longitude));
+ }
+ double fillAlpha = annotation.getDouble("alpha");
+ int fillColor = Color.parseColor(annotation.getString("fillColor"));
+ int strokeColor = Color.parseColor(annotation.getString("strokeColor"));
+ float strokeWidth = annotation.getInt("strokeWidth");
+ polygon.alpha((float) fillAlpha);
+ polygon.fillColor(fillColor);
+ polygon.strokeColor(strokeColor);
+ polygon.strokeWidth(strokeWidth);
+ view.addPolygon(polygon);
+ }
+ }
+ }
+ if (props.hasKey(PROP_DEBUG_ACTIVE)) {
+ view.setDebugActive(props.getBoolean(PROP_DEBUG_ACTIVE, false));
+ }
+ if (props.hasKey(PROP_DIRECTION)) {
+ view.setDirection(props.getFloat(PROP_DIRECTION, 0));
+ }
+ if (props.hasKey(PROP_CENTER_COORDINATE)) {
+ ReadableMap center = props.getMap(PROP_CENTER_COORDINATE);
+ double latitude = center.getDouble("latitude");
+ double longitude = center.getDouble("longitude");
+ view.setCenterCoordinate(new LatLng(latitude, longitude));
+ }
+ if (props.hasKey(PROP_ROTATION_ENABLED)) {
+ view.setRotateEnabled(props.getBoolean(PROP_ROTATION_ENABLED, true));
+ }
+ if (props.hasKey(PROP_SCROLL_ENABLED)) {
+ view.setScrollEnabled(props.getBoolean(PROP_SCROLL_ENABLED, true));
+ }
+ if (props.hasKey(PROP_STYLE_URL)) {
+ view.setStyleUrl(props.getString(PROP_STYLE_URL));
+ }
+ if (props.hasKey(PROP_STYLE_URL)) {
+ view.setZoomEnabled(props.getBoolean(PROP_ZOOM_ENABLED, true));
+ }
+ if (props.hasKey(PROP_ZOOM_LEVEL)) {
+ view.setZoomLevel(props.getFloat(PROP_ZOOM_LEVEL, 0));
+ }
+
+ super.updateView(view, props);
+ }
+}
diff --git a/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLPackage.java b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLPackage.java
new file mode 100644
index 0000000..389c60e
--- /dev/null
+++ b/android/src/main/java/com/mapbox/reactnativemapboxgl/ReactNativeMapboxGLPackage.java
@@ -0,0 +1,32 @@
+package com.mapbox.reactnativemapboxgl;
+
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.JavaScriptModule;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ViewManager;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import android.util.Log;
+
+public class ReactNativeMapboxGLPackage implements ReactPackage {
+ @Override
+ public List createNativeModules(ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List> createJSModules() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List createViewManagers(ReactApplicationContext reactContext) {
+ return Arrays.asList(
+ new ReactNativeMapboxGLManager()
+ );
+ }
+}
diff --git a/index.android.js b/index.android.js
new file mode 100644
index 0000000..8582980
--- /dev/null
+++ b/index.android.js
@@ -0,0 +1,52 @@
+var React = require('react-native');
+var { NativeModules, requireNativeComponent } = React;
+
+
+var MapView = React.createClass({
+ name: 'RCTMapbox',
+ propTypes: {
+ accessToken: React.PropTypes.string,
+ annotations: React.PropTypes.arrayOf(React.PropTypes.shape({
+ title: React.PropTypes.string,
+ subtitle: React.PropTypes.string,
+ coordinates: React.PropTypes.arrayOf(),
+ alpha: React.PropTypes.number,
+ fillColor: React.PropTypes.string,
+ strokeColor: React.PropTypes.string,
+ strokeWidth: React.PropTypes.number
+ })),
+ centerCoordinate: React.PropTypes.shape({
+ latitude: React.PropTypes.number.isRequired,
+ longitude: React.PropTypes.number.isRequired
+ }),
+ debugActive: React.PropTypes.bool,
+ direction: React.PropTypes.number,
+ rotationEnabled: React.PropTypes.bool,
+ scrollEnabled: React.PropTypes.bool,
+ styleUrl: React.PropTypes.string,
+ zoomEnabled: React.PropTypes.bool,
+ zoomLevel: React.PropTypes.number
+ },
+ getDefaultProps() {
+ return {
+ centerCoordinate: {
+ latitude: 0,
+ longitude: 0
+ },
+ debugActive: false,
+ direction: 0,
+ rotationEnabled: true,
+ scrollEnabled: true,
+ styleUrl: 'asset://styles/streets-v8.json',
+ zoomEnabled: true
+ };
+ },
+ render: function() {
+ return ();
+ }
+});
+
+
+module.exports = requireNativeComponent('RCTMapbox', MapView);
diff --git a/RCTMapboxGL.ios.js b/index.ios.js
similarity index 99%
rename from RCTMapboxGL.ios.js
rename to index.ios.js
index 0738fd5..29d30cc 100644
--- a/RCTMapboxGL.ios.js
+++ b/index.ios.js
@@ -95,7 +95,6 @@ var MapView = React.createClass({
zoomEnabled: true
};
},
-
render: function() {
return (=0.4.3"
},
@@ -26,7 +26,7 @@
},
"scripts": {
"preinstall": "./scripts/download-mapbox-gl-native-ios.sh 2.1.2",
- "test": "eslint example.js RCTMapboxGL.ios.js",
+ "test": "eslint example.js index.ios.js index.android.js",
"start": "node_modules/react-native/packager/packager.sh"
},
"devDependencies": {
diff --git a/readme.md b/readme.md
index b16ff9f..0908a1e 100644
--- a/readme.md
+++ b/readme.md
@@ -2,14 +2,21 @@
_A React Native component for building maps with [Mapbox GL](https://www.mapbox.com/mapbox-gl/)_
+
```
npm install react-native-mapbox-gl --save
```

-# [Installation](/install.md)
+# Installation
+* [iOS](/ios/install.md)
+* [Android](/ios/install.md)
-# [API](/API.md)
+# API
+* [iOS](/ios/API.md)
+* [Android](/ios/API.md)
-# [Example](/example.js)
+# Example
+* [iOS](/ios//example.js)
+* [Android](/ios//example.js)
diff --git a/scripts/download-mapbox-gl-native-ios.sh b/scripts/download-mapbox-gl-native-ios.sh
index ed0b083..9a774af 100755
--- a/scripts/download-mapbox-gl-native-ios.sh
+++ b/scripts/download-mapbox-gl-native-ios.sh
@@ -3,6 +3,7 @@
VERSION=$1
echo "Downloading Mapbox GL iOS $VERSION, this may take a minute."
+cd ios/
if ! which curl > /dev/null; then echo "curl command not found. Please install curl"; exit 1; fi;
if ! which unzip > /dev/null; then echo "unzip command not found. Please install unzip"; exit 1; fi;