@Override
  public void updateLocationMarker(Location location) {
    if (locationChangedListener != null) {
      currentUserLocation = location;
      locationChangedListener.onLocationChanged(location);
    }

    // Update clickable area
    LatLng userPosition = getUserLocation(location);
    if (userPositionClickArea == null) {
      MarkerOptions markerOptions = new MarkerOptions();
      markerOptions.position(userPosition);
      markerOptions.anchor(0.4f, 0.4f); // strange google maps bug
      markerOptions.icon(BitmapDescriptorFactory.fromBitmap(clickableBitmap));
      userPositionClickArea = googleMap.addMarker(markerOptions);
    } else {
      userPositionClickArea.setPosition(userPosition);
    }
    if (userPositionClickArea2 == null) {
      MarkerOptions markerOptions = new MarkerOptions();
      markerOptions.position(userPosition);
      markerOptions.anchor(0.6f, 0.6f); // strange google maps bug
      markerOptions.icon(BitmapDescriptorFactory.fromBitmap(clickableBitmap));
      userPositionClickArea2 = googleMap.addMarker(markerOptions);
    } else {
      userPositionClickArea2.setPosition(userPosition);
    }
  }
  private Boolean updateMarkers(ReadableArray markerArray) {
    try {
      // First clear all markers from the map
      for (Marker marker : mapMarkers) {
        marker.remove();
      }
      mapMarkers.clear();
      markerLookup.clear();

      // All markers to map
      for (int i = 0; i < markerArray.size(); i++) {
        ReadableMap markerJson = markerArray.getMap(i);
        if (markerJson.hasKey("coordinates")) {
          Marker marker = map.addMarker(createMarker(markerJson));

          if (markerJson.hasKey("id")) {
            // As we have to lookup it either way, switch it around
            markerLookup.put(marker.getId(), markerJson.getString("id"));
            markerLookup.put(markerJson.getString("id"), marker.getId().replace("m", ""));
          }

          mapMarkers.add(marker);

        } else break;
      }

      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 public void addMarker(ReadableMap config) {
   MarkerOptions options = createMarker(config);
   Marker marker = map.addMarker(options);
   mapMarkers.add(marker);
   if (config.hasKey("id")) {
     // As we have to lookup it either way, switch it around
     markerLookup.put(marker.getId(), config.getString("id"));
     markerLookup.put(config.getString("id"), marker.getId().replace("m", ""));
   }
 }
  private boolean onLocationMarkerTap(Marker marker) {
    if (userPositionClickArea == null) return false;
    if (userPositionClickArea2 == null) return false;

    if (marker.getId().equals(userPositionClickArea.getId())
        || marker.getId().equals(userPositionClickArea2.getId())) {
      if (locationMarkerTapListener != null) locationMarkerTapListener.onMarkerTapped();
      return true;
    }

    return false;
  }
  private Boolean zoomOnMarkers() {
    try {
      int padding = 150;

      LatLngBounds.Builder builder = new LatLngBounds.Builder();
      for (Marker marker : mapMarkers) {
        builder.include(marker.getPosition());
      }
      LatLngBounds bounds = builder.build();

      CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
      map.animateCamera(cu);
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
 @ReactProp(name = PROP_CLICK_MARKER)
 public void setPropClickMarker(MapView view, @Nullable Integer clickMarker) {
   WritableMap properties = getProperties();
   String key = String.valueOf(clickMarker);
   if (clickMarker == null) {
     if (properties.hasKey(PROP_CLICK_MARKER)) {
       if (markerLookup.containsKey(String.valueOf(properties.getInt(PROP_CLICK_MARKER)))) {
         Marker marker =
             mapMarkers.get(
                 Integer.parseInt(
                     markerLookup.get(String.valueOf(properties.getInt(PROP_CLICK_MARKER)))));
         marker.hideInfoWindow();
         Log.i(REACT_CLASS, "hideInfoWindow");
       }
     }
   } else {
     properties.putInt(PROP_CLICK_MARKER, clickMarker);
     if (markerLookup.containsKey(key)) {
       Marker marker = mapMarkers.get(Integer.parseInt(markerLookup.get(key)));
       marker.showInfoWindow();
       Log.i(REACT_CLASS, "showInfoWindow" + String.valueOf(marker));
     }
   }
 }
  public void updateMarkerLocation(double lat, double lng) {
    LatLng location = new LatLng(lat, lng);

    if (marker == null) {
      markerOptions = new MarkerOptions();
      markerOptions.visible(true);
      markerOptions.position(location);
      markerOptions.draggable(draggable);
      marker = googleMap.addMarker(markerOptions);
    }

    CameraPosition cameraPosition =
        new CameraPosition.Builder().target(location).zoom(zoomLevel).bearing(0).tilt(45).build();
    googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    marker.setPosition(location);
  }
  public void addMarkers(List<GridPoint> gridPointList, List<PointEntity> pointEntityList) {
    clearMap();
    Marker m;
    LatLngBounds.Builder builder = new LatLngBounds.Builder();

    for (GridPoint gridPoint : gridPointList) {
      Bitmap icon =
          gridPoint.getScore() > 10
              ? gridPoint.getScore() > 20
                  ? BitmapFactory.decodeResource(getResources(), R.drawable.red_dot)
                  : BitmapFactory.decodeResource(getResources(), R.drawable.yellow_dot)
              : BitmapFactory.decodeResource(getResources(), R.drawable.green_dot);
      float hue =
          gridPoint.getScore() > 10
              ? gridPoint.getScore() > 20
                  ? BitmapDescriptorFactory.HUE_RED
                  : BitmapDescriptorFactory.HUE_YELLOW
              : BitmapDescriptorFactory.HUE_GREEN;

      markerOptions = new MarkerOptions();
      markerOptions.visible(true);
      markerOptions.position(
          new LatLng(
              gridPoint.getLocation().getLatitude().doubleValue(),
              gridPoint.getLocation().getLongitude().doubleValue()));
      markerOptions.draggable(false);
      markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
      // markerOptions.icon(BitmapDescriptorFactory.defaultMarker(hue));

      m = googleMap.addMarker(markerOptions);
      gridMap.put(m.getId(), gridPoint);
      builder.include(m.getPosition());
    }

    for (PointEntity pointEntity : pointEntityList) {
      Bitmap icon =
          pointEntity.getPointType().equals(PointType.PERSON)
              ? BitmapFactory.decodeResource(getResources(), R.drawable.man)
              : pointEntity.getPointType().equals(PointType.POLICE_STATION)
                  ? BitmapFactory.decodeResource(getResources(), R.drawable.police)
                  : BitmapFactory.decodeResource(getResources(), R.drawable.hospital);
      markerOptions = new MarkerOptions();
      markerOptions.visible(true);
      markerOptions.position(
          new LatLng(
              pointEntity.getLocation().getLatitude().doubleValue(),
              pointEntity.getLocation().getLongitude().doubleValue()));
      markerOptions.draggable(false);
      markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));

      m = googleMap.addMarker(markerOptions);
      pointMap.put(m.getId(), pointEntity);
      builder.include(m.getPosition());
    }

    if (gridPointList.size() > 1) {
      LatLngBounds bounds = builder.build();
      CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
      googleMap.animateCamera(cu);
    } else if (gridPointList.size() > 0) {
      CameraPosition cameraPosition =
          new CameraPosition.Builder()
              .target(
                  new LatLng(
                      gridPointList.get(0).getLocation().getLatitude().doubleValue(),
                      gridPointList.get(0).getLocation().getLongitude().doubleValue()))
              .zoom(zoomLevel)
              .bearing(0)
              .tilt(45)
              .build();
      googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
    }

    markersDisplayed = true;
    heatmapDisplayed = false;
    clusterDisplayed = false;
  }
 public double getMarkerLongitude() {
   return marker.getPosition().longitude;
 }
 public double getMarkerLatitude() {
   return marker.getPosition().latitude;
 }
 public void makeMarkerDraggable() {
   draggable = true;
   if (marker != null) {
     marker.setDraggable(true);
   }
 }