Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save cesarockstar1985/89641968980b62149b66733a8690b25a to your computer and use it in GitHub Desktop.

Select an option

Save cesarockstar1985/89641968980b62149b66733a8690b25a to your computer and use it in GitHub Desktop.
package cast.com.py.castmobile3.jsinterface;
import android.content.Context;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.util.Log;
import cast.com.py.castmobile3.CastMobileActivity;
import cast.com.py.castmobile3.R;
import cast.com.py.castmobile3.datagw.CoreService;
import cast.com.py.castmobile3.helper.JsonHelper;
import cast.com.py.castmobile3.helper.LocalizationHelper;
import cast.com.py.castmobile3.helper.UiHelper;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.*;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.*;
/**
* Created by gaguilar on 24/01/19.
* Clase para manejar los metodos vinculados al uso de mapas
*/
public class MapsJsInterface {
private static final String TAG = "MapsJsInterface";
//Propiedades de marker
private static final String MARKER_TAG = "marker_tag";
private static final String MARKER_TITLE = "marker_title";
private static final String MARKER_SUBTITLE = "marker_subtitle";
private static final String MARKER_TEXT = "marker_text";
private static final String MARKER_TEXT_SIZE = "marker_text_size";
private static final String MARKER_TEXT_COLOR = "marker_text_color";
private static final String MARKER_FILL_COLOR = "marker_fill_color";
private static final String MARKER_BORDER_COLOR = "marker_border_color";
private static final String MARKER_LATITUDE = "marker_latitude";
private static final String MARKER_LONGITUDE = "marker_longitude";
private static final String MARKER_WIDTH = "marker_width";
private static final String MARKER_HEIGHT = "marker_height";
private static final String MARKER_METHOD = "marker_method";
private static final String MARKER_INFO_METHOD = "marker_info_method";
//Propiedades de linea en mapa
private static final String LINE_TYPE = "line_type";
private static final String LINE_COLOR = "line_color";
private static final String LINE_WIDTH = "line_width";
//Patrones de linea en mapa
private static final String LINE_CONTINUOUS = "line_continuous";
private static final String LINE_DASHED = "line_dashed";
//Colores
private static final String COLOR_RED = "#cc2900";
private static final String COLOR_WHITE = "#ffffff";
private static final String COLOR_BLACK = "#000000";
private static final String COLOR_PREFIX = "#";
//Propiededases de poligon en mapa
private static final String POLYGON_COORDINATES = "polygon_coordinates";
private static final String POLYGON_COLOR = "polygon_color";
private static final String POLYGON_COLOR_OPACITY = "polygon_color_opacity";
private static final String POLYGON_BORDER_COLOR = "polygon_border_color";
//Metodo encargado de agregar marker, lineas y poligonos a mapa
//markersJsonString (Mapa de mapas), lineJsonString (mapa), polygonsJsonString (Lista de mapas)
public static void addElementsInMap(final Context context, final String markersJsonString,
final String lineJsonString, final String polygonsJsonString) {
Log.i(TAG, "Add Elements In Map STARTED");
try {
final CastMobileActivity castMobileActivity = (CastMobileActivity) context;
CoreService.getInstance().getHandler().post(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
Marker marker;
LatLng coordinates;
LatLngBounds.Builder builder = new LatLngBounds.Builder();
Bitmap bmp = buildBitmap();
Canvas canvas = new Canvas(bmp);
final Map<String, Object> markerLinkedMap;
castMobileActivity.getGoogleMap().clear(); // Borra el contenido previo del mapa
if (castMobileActivity.getUserLocation() != null) {
builder.include(castMobileActivity.getUserLocation()); // Agrega la ubiacion del usuario al mapa
}
// Se obtienen los datos de la linea entre markers en caso que se hayan parametrizado
PolylineOptions markersLine = getMarkersLine(lineJsonString);
//Se convierten los PNG de modelo como un objeto dibujable para manipular sus propiedades
Drawable drawableFill = context.getResources().getDrawable(R.drawable.circle, null);
Drawable drawableBorder = context.getResources().getDrawable(R.drawable.border, null);
//Se convierte a un objeto java el json con los datos parametrizados para los markers
markerLinkedMap = parseJsonToLinkedMap(markersJsonString, true);
Iterator<Map.Entry<String, Object>> iterator = markerLinkedMap.entrySet().iterator();
Map.Entry<String, Object> entry;
HashMap<String, String> markerData;
while (iterator.hasNext()) {
try {
entry = iterator.next();
markerData = (HashMap<String, String>) entry.getValue();
compatMarkersVersion(markerData); // Compatibilizar versiones de mapa
validateMarkerData(markerData); // Valida las propiedades del marker
double latitude = Double.parseDouble(markerData.get(MARKER_LATITUDE));
double longitude = Double.parseDouble(markerData.get(MARKER_LONGITUDE));
if (latitude != 0 && longitude != 0) {
//Log.i(TAG, "lat.: " + latitude + " long.: " + longitude);
coordinates = new LatLng(latitude, longitude);
paintMarker(canvas, drawableFill, drawableBorder, markerData); // Se pinta el marker
marker = castMobileActivity.getGoogleMap().addMarker(new MarkerOptions().title(markerData.get(MARKER_TITLE)).position(coordinates).icon(BitmapDescriptorFactory.fromBitmap(bmp)).snippet(markerData.get(MARKER_SUBTITLE)).anchor(0.5f, 0.5f));
marker.setTag(markerData.get(MARKER_TAG));
builder.include(coordinates);
if (markersLine != null) {
markersLine.add(coordinates);
}
/*
Se agrega la posibilidad que os markers puedan recibir metodos personalizados a ejecutar
a traves de las nuevas propiedades MARKER_METHOD y MARKER_INFO_METHOD.
*/
castMobileActivity.getGoogleMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
try {
/*
Se accede al mapa que contiene la información de cada marker. Se realiza de esta forma para poder
obtener la función que corresponde al marker pulsado.
*/
HashMap<String, String> markerData = (HashMap<String, String>) markerLinkedMap.get(marker.getTag());
//Se obtiene la funcion que corresponde al marker.
String markerMethod = markerData.get(MARKER_METHOD);
if (markerMethod != null) {
castMobileActivity.getWebView().loadUrl("javascript:" + markerMethod);
} else {
castMobileActivity.getWebView().loadUrl("javascript:cm_scrollIntoView('" + marker.getTag() + "')");
}
} catch (Throwable ignored) {}
return false;
}
});
castMobileActivity.getGoogleMap().setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
try {
/*
Se accede al mapa que contiene la información de cada marker. Se realiza de esta forma para poder
obtener la función que corresponde al marker pulsado.
*/
HashMap<String, String> markerData = (HashMap<String, String>) markerLinkedMap.get(marker.getTag());
//Se obtiene la funcion que corresponde al marker.
String markerInfoMethod = markerData.get(MARKER_INFO_METHOD);
if (markerInfoMethod != null) {
castMobileActivity.getWebView().loadUrl("javascript:" + markerInfoMethod);
} else {
castMobileActivity.getWebView().loadUrl("javascript:cm_scrollIntoView('" + marker.getTag() + "')");
}
} catch (Throwable e) {
Log.e(TAG, "onInfoWindowClick: ", e);
}
}
});
} else {
Log.i(TAG, "lat y long 0 no se agrega");
}
} catch (Throwable th) {
Log.e(TAG, "ERROR adding marker on map: " + th.getMessage(), th);
}
}
// Agrega la linea al mapa
if (markersLine != null) {
castMobileActivity.getGoogleMap().addPolyline(markersLine);
}
//Agrega los poligonos al mapa
addPolygonsOnMap(castMobileActivity.getGoogleMap(), builder, polygonsJsonString);
//Se establece límite para visualización teniendo en cuenta los objetos agregados
mapMoveCamera(castMobileActivity,builder, markersLine);
} catch (Throwable t0) {
Log.e(TAG, "addElementInMap: ", t0);
}
}
});
} catch (Throwable t) {
Log.e(TAG, "addElementInMap: ", t);
}
Log.i(TAG, "Add Elements In Map FINISHED");
}
private static void compatMarkersVersion(HashMap<String, String> markerData) {
if (markerData.containsKey("latitude") && markerData.containsKey("longitude")) {
markerData.put(MARKER_LATITUDE, markerData.get("latitude"));
markerData.put(MARKER_LONGITUDE, markerData.get("longitude"));
markerData.put(MARKER_TITLE, markerData.get("title"));
markerData.put(MARKER_SUBTITLE, markerData.get("subtitle"));
markerData.put(MARKER_TAG, markerData.get("route_detail_id"));
markerData.put(MARKER_FILL_COLOR, COLOR_RED);
markerData.put(MARKER_BORDER_COLOR, COLOR_WHITE);
markerData.remove("latitude");
markerData.remove("longitude");
markerData.remove("title");
markerData.remove("subtitle");
markerData.remove("route_detail_id");
}
}
private static PolylineOptions getMarkersLine(String lineJsonString) {
PolylineOptions markersLine = null;
Map<String, Object> map;
try {
map = parseJsonToLinkedMap(lineJsonString, false);
if(!map.isEmpty()){
markersLine = buildPolylineOptions(map);
}
} catch (Throwable t) {
Log.e(TAG, "getMarkersLine: No se lanza la excepcion: ", t);
}
return markersLine;
}
//Se construye objeto para pintar texto
private static TextPaint buildTxtPaint(int txtSize, String color){
TextPaint paint = new TextPaint();
try{
paint.setTextSize(UiHelper.convertDpToPixel(txtSize));
paint.setColor(Color.parseColor(color));
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
}catch (Throwable th){
Log.e(TAG, "ERROR in buildTxtPaint method: "+th, th);
throw th;
}
return paint;
}
private static Bitmap buildBitmap(){
Bitmap bmp;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
bmp = Bitmap.createBitmap((int) UiHelper.convertDpToPixel(40), (int) UiHelper.convertDpToPixel(40), conf);
return bmp;
}
private static PolylineOptions buildPolylineOptions(Map<String, Object> lineDataMap) throws Throwable {
PolylineOptions line = new PolylineOptions();
try{
validateLineData(lineDataMap);
line.color(Color.parseColor(lineDataMap.get(LINE_COLOR).toString()));
line.width(UiHelper.convertDpToPixel(Integer.parseInt(lineDataMap.get(LINE_WIDTH).toString())));
if(lineDataMap.get(LINE_TYPE).toString().equals(LINE_DASHED)){
line.pattern(Arrays.asList(new Dash(5), new Gap(5)));
}
}catch (Throwable th){
Log.e(TAG, "ERROR to build line object: "+th,th);
throw th;
}
return line;
}
//Metodo encargado de validar el estilo de la linea segun lo parametrizado y de agregar valores por defecto si corresponde
private static void validateLineData(Map<String, Object> lineDataMap){
try{
if(!lineDataMap.containsKey(LINE_TYPE) || lineDataMap.get(LINE_TYPE).equals("")){
lineDataMap.put(LINE_TYPE, LINE_CONTINUOUS);
}
if(!lineDataMap.containsKey(LINE_COLOR) || lineDataMap.get(LINE_COLOR).equals("")){
lineDataMap.put(LINE_COLOR, COLOR_BLACK);
}
if(!lineDataMap.containsKey(LINE_WIDTH) || lineDataMap.get(LINE_WIDTH).equals("")){
lineDataMap.put(LINE_WIDTH, 2);
}
}catch (Throwable th){
Log.e(TAG, "validateLineData: "+th, th);
throw th;
}
}
private static void drawTextOnCanvas(Canvas canvas, int width, int height, TextPaint textPaint,String text){
try{
Rect rect = new Rect();
textPaint.getTextBounds(text, 0, text.length(), rect);
int x = width / 2 - rect.width() / 2 - rect.left;
int y = height / 2 + rect.height() / 2 - rect.bottom;
canvas.drawText(text, x, y, textPaint);
}catch (Throwable th){
Log.e(TAG, "drawTextOnCanvas: "+th,th);
throw th;
}
}
//Metodo encargado de validar lo parametrizado para el estilo del marker y proveer de valores por defecto si corresponde
private static void validateMarkerData(HashMap<String, String> dataMap) throws Exception {
try{
if (!dataMap.containsKey(MARKER_LATITUDE) || !dataMap.containsKey(MARKER_LONGITUDE)) {
throw new Exception("Latitude or Longitude NULL for Marker!");
}
if (!dataMap.containsKey(MARKER_TEXT) || dataMap.get(MARKER_TEXT).equals("")){
dataMap.put(MARKER_TEXT, "");
}
if(!dataMap.containsKey(MARKER_TEXT_SIZE) || dataMap.get(MARKER_TEXT_SIZE).equals("")){
dataMap.put(MARKER_TEXT_SIZE, "15");
}
if(!dataMap.containsKey(MARKER_TEXT_COLOR) || dataMap.get(MARKER_TEXT_COLOR).equals("")){
dataMap.put(MARKER_TEXT_COLOR, COLOR_BLACK);
}
if(!dataMap.containsKey(MARKER_WIDTH) || dataMap.get(MARKER_WIDTH).equals("")){
dataMap.put(MARKER_WIDTH, "25");
}
if(!dataMap.containsKey(MARKER_HEIGHT) || dataMap.get(MARKER_HEIGHT).equals("")){
dataMap.put(MARKER_HEIGHT, "25");
}
if(!dataMap.containsKey(MARKER_FILL_COLOR) || dataMap.get(MARKER_FILL_COLOR).equals("")){
dataMap.put(MARKER_FILL_COLOR, COLOR_WHITE);
}
if(!dataMap.containsKey(MARKER_BORDER_COLOR) || dataMap.get(MARKER_BORDER_COLOR).equals("")){
dataMap.put(MARKER_BORDER_COLOR, COLOR_WHITE);
}
}catch (Throwable th){
Log.e(TAG, "validateMarkerData: "+th);
throw th;
}
}
private static Map<String, Object> parseJsonToLinkedMap(String jsonString, boolean throwException) throws Throwable {
Map<String, Object> map = new LinkedHashMap<>();
try{
if(jsonString != null && !jsonString.equals("")){
JSONObject jsObject = new JSONObject(jsonString);
map = JsonHelper.toLinkedMap(jsObject);
}
}catch (Throwable th){
Log.e(TAG, "parseJsonToLinkedMap: "+th,th);
if (throwException) {
throw th;
}
}
return map;
}
//Metodo encargado de validar lo parametrizado para el estilo del poligono y proveer de valores por defecto si corresponde
private static void validatePolygonData(Map<String, Object> polygonProperties) throws Throwable {
try{
if(!polygonProperties.containsKey(POLYGON_COORDINATES) || polygonProperties.get(POLYGON_COORDINATES).equals("")){
throw new Exception("Coordinates for Zone are empty!");
}
if(!polygonProperties.containsKey(POLYGON_COLOR) || polygonProperties.get(POLYGON_COLOR).equals("")){
polygonProperties.put(POLYGON_COLOR, "FF0000"); //Red color
}
if(!polygonProperties.containsKey(POLYGON_COLOR_OPACITY) || polygonProperties.get(POLYGON_COLOR_OPACITY).equals("")){
polygonProperties.put(POLYGON_COLOR_OPACITY, "30");
}
if(!polygonProperties.containsKey(POLYGON_BORDER_COLOR) || polygonProperties.get(POLYGON_BORDER_COLOR).equals("")){
polygonProperties.put(POLYGON_BORDER_COLOR, COLOR_PREFIX + String.valueOf(polygonProperties.get(POLYGON_COLOR)));
}
}catch (Throwable th){
Log.e(TAG, "validatePolygonData: "+th, th);
throw th;
}
}
//Metodo encargado de dar el estilo al Marker segun lo parametrizado
private static void paintMarker(Canvas canvas, Drawable drawableFill, Drawable drawableBorder, HashMap<String, String> markerPropertiesMap) throws Throwable{
try{
//Se obtiene el anchor y largor parametrizado
int right = (int) UiHelper.convertDpToPixel(Integer.parseInt(markerPropertiesMap.get(MARKER_WIDTH)));
int bottom = (int) UiHelper.convertDpToPixel(Integer.parseInt(markerPropertiesMap.get(MARKER_HEIGHT)));
//Se pintan el relleno y borde de los PNG, y se agregan al lienzo
drawableFill.setBounds(0, 0, right, bottom);
DrawableCompat.setTint(DrawableCompat.wrap(drawableFill), Color.parseColor(markerPropertiesMap.get(MARKER_FILL_COLOR)));
drawableFill.draw(canvas);
drawableBorder.setBounds(0, 0,right, bottom);
DrawableCompat.setTint(DrawableCompat.wrap(drawableBorder), Color.parseColor(markerPropertiesMap.get(MARKER_BORDER_COLOR)));
drawableBorder.draw(canvas);
//Se agrega el texto que ira dentro del marker en el lienzo segun lo parametrizado
TextPaint textPaint = buildTxtPaint(Integer.parseInt(markerPropertiesMap.get(MARKER_TEXT_SIZE)), markerPropertiesMap.get(MARKER_TEXT_COLOR));
drawTextOnCanvas(canvas, right, bottom, textPaint,markerPropertiesMap.get(MARKER_TEXT));
}catch (Throwable th){
Log.e(TAG, "paintMarker: "+th,th);
throw th;
}
}
//Metodo encargado de agregar los poligonos al mapa
private static boolean addPolygonsOnMap(GoogleMap map, LatLngBounds.Builder builder, String polygonsJsonString) throws Throwable {
boolean drawPolygons = false;
try{
if(polygonsJsonString != null && !polygonsJsonString.equals("")){
JSONArray jsArray = new JSONArray(polygonsJsonString);
Map<String, Object> polygonProperties;
PolygonOptions polygonOptions;
String[] polygonCoordinate;
LatLng latLng;
for(int i=0; i<jsArray.length(); i++){
try{
polygonProperties = JsonHelper.toMap(new JSONObject(String.valueOf(jsArray.get(i))));
//Se validan los datos parametrizados por cada poligono
validatePolygonData(polygonProperties);
//Se crea objeto polygonOptions y se le van agregando las propiedades parametrizadas
polygonCoordinate = String.valueOf(polygonProperties.get(POLYGON_COORDINATES)).split(" ");
polygonOptions = new PolygonOptions();
polygonOptions.strokeColor(Color.parseColor(String.valueOf(polygonProperties.get(POLYGON_BORDER_COLOR))));
polygonOptions.strokeWidth(UiHelper.convertDpToPixel(1));
polygonOptions.fillColor(Color.parseColor(COLOR_PREFIX+polygonProperties.get(POLYGON_COLOR_OPACITY)+polygonProperties.get(POLYGON_COLOR)));
for (int j = 0; j < polygonCoordinate.length; j = j + 2) {
latLng = new LatLng(Double.valueOf(polygonCoordinate[j]), Double.valueOf(polygonCoordinate[j + 1]));
polygonOptions.add(latLng);
builder.include(latLng);
}
//Se agrega poligono a mapa
map.addPolygon(polygonOptions);
drawPolygons = true;
}catch (Throwable th){
Log.e(TAG, "ERROR adding polygon on map: "+th,th);
}
}
}
}catch (Throwable th){
Log.e(TAG, "addPolygonsOnMap: "+th,th);
throw th;
}
return drawPolygons;
}
//Metodo encargado de establecer limite de visualizacion en mapa
private static void mapMoveCamera(CastMobileActivity castMobileActivity, LatLngBounds.Builder builder, PolylineOptions line){
try{
boolean useDefaultBounds = false;
GoogleMap map = castMobileActivity.getGoogleMap();
DisplayMetrics displaymetrics = new DisplayMetrics();
int width = 0;
LatLngBounds bounds = null;
try {
/*
Toma los bounds de acuerdo a las coordenadas que fue almacenando a lo largo de la carga de elementos
al mapa. En caso de no contar con ningun punto, se lanza una excepcion y se toma la visualizacion
de Paraguay por defecto.
*/
bounds = builder.build();
castMobileActivity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
width = displaymetrics.widthPixels;
} catch (Throwable t) {
Log.e(TAG, "mapMoveCamera: " + t);
useDefaultBounds = true;
}
if (useDefaultBounds) {
//Zoom sobre Paraguay por defecto
castMobileActivity.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
width = displaymetrics.widthPixels;
//TODO se agrego usersetting que contiene el mapBound configurado por servicio.
// Se puede obtener del UserSettingsHelper key = "map.bound"; setting = "map";
LatLng latLng1 = new LatLng(-27.5800247192383, -62.6437759399414);
LatLng latLng2 = new LatLng(-19.2968196868896, -54.25);
bounds = new LatLngBounds(latLng1, latLng2);
}
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, width, (int) UiHelper.convertDpToPixel(200),(int) UiHelper.convertDpToPixel(20)));
}catch (Throwable th){
Log.e(TAG, "mapMoveCamera: "+th,th);
}
}
public static void zoomMapToUserLocation() {
LocalizationHelper.zoomMapToLastKnowLocation();
}
public static void zoomMapToSubjectLocation(final Context context, final double latitude, final double longitude) {
Log.i(TAG, "Zoom to Subject in Map Start");
try {
final CastMobileActivity castMobileActivity = (CastMobileActivity) context;
CoreService.getInstance().getHandler().post(new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
try {
LatLng coordinates;
LatLngBounds.Builder builder = new LatLngBounds.Builder();
coordinates = new LatLng(latitude, longitude);
builder.include(coordinates);
mapMoveCamera(castMobileActivity, builder, null);
} catch (Throwable t0) {
Log.e(TAG, "zoomMapToSubjectLocation: ", t0);
}
}
});
} catch (Throwable t) {
Log.e(TAG, "zoomMapToSubjectLocation: ", t);
}
Log.i(TAG, "Zoom to Subject in Map Finished");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment