TinyWeatherForecastGermanyM.../app/src/main/java/de/kaffeemitkoffein/tinyweatherforecastgermany/WeatherWarningActivity.java

1375 lines
64 KiB
Java

/*
* This file is part of TinyWeatherForecastGermany.
*
* Copyright (c) 2020, 2021, 2022, 2023, 2024 Pawel Dube
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.kaffeemitkoffein.tinyweatherforecastgermany;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.*;
import android.content.pm.PackageManager;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.UnderlineSpan;
import android.util.DisplayMetrics;
import android.view.*;
import android.widget.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
public class WeatherWarningActivity extends Activity {
ArrayList<WeatherWarning> weatherWarnings;
ArrayList<WeatherWarning> localWarnings;
Weather.WeatherLocation ownLocation;
View.OnTouchListener mapTouchListener;
ArrayList<Polygon> polygoncache;
ArrayList<Polygon> excluded_polygoncache;
ImageView germany;
ImageView warningactivity_map_collapsed;
RelativeLayout mapcontainer;
ProgressBar rainSlideProgressBar;
TextView rainSlideProgressBarText;
TextView rainSlideTime;
ImageView rainDescription;
Bitmap germanyBitmap;
Bitmap warningsBitmap;
Bitmap radarBitmap;
Bitmap administrativeBitmap;
Bitmap visibleBitmap;
ZoomableImageView mapZoomable;
RelativeLayout map_collapsed_container;
LinearLayout warningactivityMapinfoContainer;
boolean deviceIsLandscape;
private GestureDetector gestureDetector;
ListView weatherList;
WeatherWarningAdapter weatherWarningAdapter;
Context context;
ActionBar actionBar;
ScheduledExecutorService scheduledExecutorService;
boolean hide_rain = false;
boolean hide_admin = true;
WeatherLocationManager weatherLocationManager;
RelativeLayout gpsProgressHolder;
Bundle zoomMapState = null;
RadarMN2.MercatorProjectionTile mercatorProjectionTile;
boolean forceWeatherUpdateFlag = false;
static float MAP_PIXEL_WIDTH;
static float MAP_PIXEL_HEIGHT;
public final static String WEATHER_WARNINGS_UPDATE="WEATHER_WARNINGS_UPDATE";
public final static String WEATHER_WARNINGS_UPDATE_RESULT="WEATHER_WARNINGS_UPDATE_RESULT";
public final static String ACTION_RAINRADAR_UPDATE="ACTION_RAINRADAR_UPDATE";
public final static String SIS_ZOOMMAPSTATEBUNDLE="ZOOMMAPSTATEBUNDLE";
public final static String SIS_HIDERAIN="HIDERAIN";
public final static String SIS_HIDEADMIN="HIDEADMIN";
PopupWindow hintPopupWindow = null;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent intent) {
if (intent!=null){
// update warning display if warnings have been updated
if (intent.getAction().equals(WEATHER_WARNINGS_UPDATE)) {
weatherWarnings = WeatherWarnings.getCurrentWarnings(getApplicationContext(),true);
displayWarnings();
updateActionBarLabels();
hideProgressBar();
}
if (intent.hasExtra(WEATHER_WARNINGS_UPDATE_RESULT)){
// gets result if update was successful, currently not used
boolean updateResult = intent.getBooleanExtra(WEATHER_WARNINGS_UPDATE_RESULT,false);
}
if (intent.getAction().equals(MainActivity.MAINAPP_HIDE_PROGRESS)){
forceWeatherUpdateFlag = false;
hideProgressBar();
}
}
}
};
private int nextRainSlide = 0;
private int lastDrawnRainSlide = 0;
private long rainSlidesStartTime = 0;
private boolean cancelRainSlides = false;
private boolean rainSlidesRunning = false;
private boolean validSlideSetObtained = false;
public final static int RAINSLIDEDELAY=750;
private boolean isNextRainSlide(){
if (nextRainSlide==lastDrawnRainSlide+1){
return true;
}
if (nextRainSlide==0){
if (lastDrawnRainSlide==APIReaders.RadarMNSetGeoserverRunnable.DATASET_SIZE){
return true;
}
}
return false;
}
private boolean rainDrawLock = false;
private final Runnable rainRadarRunnable = new Runnable() {
@Override
public void run() {
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
nextRainSlide=0;
rainSlidesRunning = true;
while (!cancelRainSlides){
long startTime = Calendar.getInstance().getTimeInMillis();
rainDrawLock = true;
runOnUiThread(new Runnable() {
@Override
public void run() {
nextRainSlide++;
drawRadarSlide(nextRainSlide);
rainDrawLock = false;
}
});
if (nextRainSlide>APIReaders.RadarMNSetGeoserverRunnable.DATASET_SIZE){
nextRainSlide=0;
}
long stopTime = Calendar.getInstance().getTimeInMillis();
long waitTime = RAINSLIDEDELAY - (stopTime-startTime);
if (waitTime>0){
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
// do nothing
}
} else {
while (rainDrawLock){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// do nothing
}
}
}
}
rainSlidesRunning = false;
cancelRainSlides = false;
}
};
private synchronized void startRainRadar(){
if (!hide_rain){
if (!rainSlidesRunning){
// make sure not to start rain radar before views are created
germany.post(new Runnable() {
@Override
public void run() {
new Thread(rainRadarRunnable).start();
}
});
}
}
}
APIReaders.RadarMNSetGeoserverRunnable radarMNSetGeoserverRunnable;
View.OnTouchListener forwardRainSlidesOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float position = motionEvent.getX()/ view.getWidth();
nextRainSlide = Math.round(position * 24f);
return true;
}
};
APIReaders.WeatherWarningsRunnable weatherWarningsUpdateRunnable;
@Override
public void onSaveInstanceState(Bundle state){
if (mapZoomable != null){
zoomMapState = mapZoomable.saveZoomViewState();
}
if (zoomMapState!=null){
state.putBundle(SIS_ZOOMMAPSTATEBUNDLE,zoomMapState);
}
state.putBoolean(SIS_HIDERAIN,hide_rain);
state.putBoolean(SIS_HIDEADMIN,hide_admin);
super.onSaveInstanceState(state);
}
@Override
protected void onRestoreInstanceState(Bundle state){
super.onRestoreInstanceState(state);
// do nothing here for the moment
}
@Override
protected void onResume() {
super.onResume();
cancelRainSlides=false;
registerForBroadcast();
if (germany==null){
germany = (ImageView) findViewById(R.id.warningactivity_map);
}
PrivateLog.log(getApplicationContext(),PrivateLog.WARNINGS,PrivateLog.INFO,"app resumed.");
if (WeatherSettings.GPSAuto(context)){
weatherLocationManager.checkLocation();
}
if (WeatherSettings.Updates.isSyncDue(context,WeatherSettings.Updates.Category.WARNINGS)){
PrivateLog.log(context,PrivateLog.WARNINGS,PrivateLog.INFO,"Weather warnings are outdated, updating data.");
scheduledExecutorService.execute(weatherWarningsUpdateRunnable);
} else {
weatherWarnings = WeatherWarnings.getCurrentWarnings(getApplicationContext(),true);
PrivateLog.log(context,PrivateLog.WARNINGS,PrivateLog.INFO,"Weather warnings are up to date, showing the data available.");
// displayWarnings() must be in scheduledExecutorService queue to make sure it is executed before
// radarMNSetGeoserverRunnable (see below)
scheduledExecutorService.execute(new Runnable() {
@Override
public void run() {
displayWarnings();
}
});
}
scheduledExecutorService.execute(radarMNSetGeoserverRunnable);
}
@Override
protected void onPause(){
cancelRainSlides = true;
unregisterReceiver(receiver);
super.onPause();
PrivateLog.log(getApplicationContext(),PrivateLog.WARNINGS,PrivateLog.INFO,"app paused.");
}
@Override
protected void onDestroy() {
super.onDestroy();
if (hintPopupWindow!=null){
if (hintPopupWindow.isShowing()){
hintPopupWindow.dismiss();
WeatherSettings.setHintCounter2(context,WeatherSettings.getHintCounter2(context)-1);
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
PrivateLog.log(getApplicationContext(),PrivateLog.WARNINGS,PrivateLog.INFO,"WeatherWarningActivity started.");
try {
ThemePicker.SetTheme(this);
} catch (Exception e){
PrivateLog.log(context,PrivateLog.WARNINGS,PrivateLog.INFO,"Error setting theme in WeatherWarnings activity.");
}
super.onCreate(savedInstanceState);
context = getApplicationContext();
mercatorProjectionTile = RadarMN2.getRadarMapMercatorProjectionTile(context);
mercatorProjectionTile.setScaleFactor(RadarMN2.getScaleFactor(context));
rainSlidesStartTime = WeatherSettings.getPrefRadarLastdatapoll(context);
WeatherSettings.setRotationMode(this);
setContentView(R.layout.activity_weatherwarning);
registerForBroadcast();
// try to restore zoom factor if it is available from the savedInstanceState
if (savedInstanceState!=null){
Bundle bundle = savedInstanceState.getBundle(SIS_ZOOMMAPSTATEBUNDLE);
if (bundle!=null){
zoomMapState = bundle;
}
hide_rain = savedInstanceState.getBoolean(SIS_HIDERAIN,!WeatherSettings.showRadarByDefault(getApplicationContext()));
hide_admin = savedInstanceState.getBoolean(SIS_HIDEADMIN,!WeatherSettings.showAdminMapByDefault(getApplicationContext()));
} else {
hide_rain = !WeatherSettings.showRadarByDefault(getApplicationContext());
hide_admin = !WeatherSettings.showAdminMapByDefault(getApplicationContext());
}
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// action bar layout
actionBar = getActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME|ActionBar.DISPLAY_HOME_AS_UP|ActionBar.DISPLAY_SHOW_TITLE);
mapcontainer = (RelativeLayout) findViewById(R.id.warningactivity_mapcontainer);
map_collapsed_container = (RelativeLayout) findViewById(R.id.warningactivity_map_collapsed_container);
warningactivity_map_collapsed = (ImageView) findViewById(R.id.warningactivity_map_collapsed);
warningactivityMapinfoContainer = (LinearLayout) findViewById(R.id.warningactivity_mapinfo_container);
if (warningactivity_map_collapsed!=null){
warningactivity_map_collapsed.setImageResource(WeatherIcons.getIconResource(context,WeatherIcons.MAP_COLLAPSED));
}
// in layout w6600dp-land this element does not exist. This is the safest way to
// limit collapse-function to portrait mode.
if (map_collapsed_container!=null){
deviceIsLandscape = false;
map_collapsed_container.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (germany!=null){
showMap();
}
return true;
}
});
} else {
deviceIsLandscape = true;
}
rainSlideProgressBar = (ProgressBar) findViewById(R.id.warningactivity_rainslideprogressbar);
rainSlideProgressBarText = (TextView) findViewById(R.id.warningactivity_rainslideprogressbartext);
rainSlideTime = (TextView) findViewById(R.id.warningactivity_rainslidetime);
rainSlideTime.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
nextRainSlide=0;
}
});
rainDescription = (ImageView) findViewById(R.id.warningactivity_mapinfo);
rainDescription.setOnTouchListener(forwardRainSlidesOnTouchListener);
gpsProgressHolder = (RelativeLayout) findViewById(R.id.gps_progress_holder);
germany = (ImageView) findViewById(R.id.warningactivity_map);
// this is to display the osm notice properly in the bottom-right map corner as a textview aligned to the
// right border of the bitmap inside the imageview.
germany.post(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
// get the scale matrix from the imageview to calculate the bitmap size inside the imageview
float[] matrix = new float[9];
germany.getImageMatrix().getValues(matrix);
float scaledMapWidth=germany.getDrawable().getIntrinsicWidth()*matrix[Matrix.MSCALE_X];
float scaledMapHeight=germany.getDrawable().getIntrinsicHeight()*matrix[Matrix.MSCALE_Y];
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
// calculate the offset of the textview
int marginRight = Math.round((displayMetrics.widthPixels-scaledMapWidth)/2);
// tweak offset for landscape mode
if (deviceIsLandscape){
RelativeLayout warningactivityLeftcontainer = (RelativeLayout) findViewById(R.id.warningactivity_leftcontainer);
marginRight = Math.round((warningactivityLeftcontainer.getWidth() - scaledMapWidth)/2);
}
// create the textview
TextView newTextView = new TextView(context);
// underline the text without the (c)
String osmString = context.getResources().getString(R.string.map_attribution);
if (WeatherSettings.appReleaseIsUserdebug()){
osmString = osmString + " " +context.getResources().getString(R.string.map_attribution_link);
}
SpannableString spannableString = new SpannableString(osmString);
spannableString.setSpan(new UnderlineSpan(),2,spannableString.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
newTextView.setText(spannableString);
newTextView.setAutoLinkMask(1);
newTextView.setTextSize(12);
if (!WeatherSettings.appReleaseIsUserdebug()){
newTextView.setTextSize(10);
}
newTextView.setVisibility(View.VISIBLE);
newTextView.setTextColor(ThemePicker.getColor(context,ThemePicker.ThemeColor.CYAN));
newTextView.setBackgroundColor(ThemePicker.getColor(context,ThemePicker.ThemeColor.PRIMARYLIGHT));
newTextView.setPadding(2,1,2,1);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(2,1,marginRight,1);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
newTextView.setLayoutParams(layoutParams);
RelativeLayout warningactivity_mapcontainer = (RelativeLayout) findViewById(R.id.warningactivity_mapcontainer);
final int newTextViewId = View.generateViewId();
newTextView.setId(newTextViewId);
warningactivity_mapcontainer.addView(newTextView);
// make the textview clickable to open the license link
newTextView.post(new Runnable() {
@Override
public void run() {
final TextView newTV = (TextView) findViewById(newTextViewId);
newTV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String osmUri = "https://openstreetmap.org/copyright";
Intent openLicenseIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(osmUri));
try {
startActivity(openLicenseIntent);
} catch (ActivityNotFoundException e){
Toast.makeText(context,osmUri,Toast.LENGTH_LONG).show();
}
}
});
// make the textview disappear after 7 sec;
// in debug builds, the textview does not disappear
if (!WeatherSettings.appReleaseIsUserdebug()){
newTV.postDelayed(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
newTV.setVisibility(View.GONE);
newTV.setOnClickListener(null);
}
});
}
},7000);
}
}
});
}
});
}
});
radarMNSetGeoserverRunnable = new APIReaders.RadarMNSetGeoserverRunnable(getApplicationContext()){
@Override
public void onProgress(long startTime, final int progress) {
if (progress==1){
rainSlidesStartTime = startTime;
runOnUiThread(new Runnable() {
@Override
public void run() {
germany.post(new Runnable() {
@Override
public void run() {
if (!hide_rain){
drawRadarSlide(0);
}
}
});
}
});
}
updateRainSlideProgressBar(progress);
}
@Override
public void onFinished(long startTime, boolean success){
super.onFinished(startTime,success);
if (success){
validSlideSetObtained = true;
germany.post(new Runnable() {
@Override
public void run() {
startRainRadar();
}
});
} else {
validSlideSetObtained = false;
}
runOnUiThread(new Runnable() {
@Override
public void run() {
rainSlideProgressBar.setVisibility(View.INVISIBLE);
rainSlideProgressBarText.setVisibility(View.INVISIBLE);
}
});
}
};
weatherLocationManager = new WeatherLocationManager(context){
@Override
public void newLocation(Location location){
super.newLocation(location);
Weather.WeatherLocationFinder weatherLocationFinder = new Weather.WeatherLocationFinder(context,location){
@Override
public void newWeatherLocation(Weather.WeatherLocation weatherLocation){
ownLocation = weatherLocation;
displayWarnings();
}
};
weatherLocationFinder.run();
}
};
weatherWarningsUpdateRunnable = new APIReaders.WeatherWarningsRunnable(getApplicationContext()) {
@Override
public void onStart() {
showProgressBar();
super.onStart();
}
@Override
public void onNegativeResult() {
hideProgressBar();
displayWarnings();
PrivateLog.log(context,PrivateLog.WARNINGS,PrivateLog.ERR,"Getting warnings failed.");
super.onNegativeResult();
}
@Override
public void onPositiveResult(ArrayList<WeatherWarning> warnings) {
hideProgressBar();
WeatherSettings.Updates.setLastUpdate(context,WeatherSettings.Updates.Category.WARNINGS,Calendar.getInstance().getTimeInMillis());
PrivateLog.log(context,PrivateLog.WARNINGS,PrivateLog.INFO,"Updated warnings: "+warnings.size()+" records.");
weatherWarnings = warnings;
for (int i=0; i<weatherWarnings.size(); i++){
weatherWarnings.get(i).initPolygons(context);
}
super.onPositiveResult(warnings);
// finally do a sync of other parameters; if nothing is due, nothing will happen
// warnings will be also ignored, because setLastUpdate was called.
scheduledExecutorService.execute(new Runnable() {
@Override
public void run() {
ContentResolver.requestSync(MainActivity.getManualSyncRequest(context,WeatherSyncAdapter.UpdateFlags.FLAG_UPDATE_DEFAULT));
}
});
displayWarnings();
}
};
WeatherSettings.saveGPSfixtime(context,0);
// set to station, perhaps override with current location later
ownLocation = WeatherSettings.getSetStationLocation(getApplicationContext());
getApplication().registerActivityLifecycleCallbacks(weatherLocationManager);
weatherLocationManager.setView(gpsProgressHolder);
weatherLocationManager.registerCancelButton((Button) findViewById(R.id.cancel_gps));
popupHint();
}
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.weatherwarning_activity,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem mi) {
int item_id = mi.getItemId();
if (item_id == R.id.menu_refresh) {
if (mapZoomable!=null){
zoomMapState = mapZoomable.saveZoomViewState();
}
PrivateLog.log(this, PrivateLog.WARNINGS,PrivateLog.INFO, "starting update of weather warnings");
SyncRequest syncRequest = MainActivity.getManualSyncRequest(context,WeatherSyncAdapter.UpdateFlags.FLAG_UPDATE_WARNINGS);
ContentResolver.requestSync(syncRequest);
forceWeatherUpdateFlag = true;
showProgressBar();
// force update or rain radar if shown
if (!hide_rain){
cancelRainSlides=true;
}
return true;
}
if (item_id==R.id.hide_rain) {
if ((hide_rain) && (hide_admin)){
hide_rain = false;
} else
if ((!hide_rain) && (hide_admin)){
hide_admin = false;
} else
if (!hide_rain) {
hide_rain = true;
}
else {
hide_rain = true; hide_admin = true;
}
if (!hide_rain){
germany.post(new Runnable() {
@Override
public void run() {
startRainRadar();
}
});
} else {
if (rainSlidesRunning){
cancelRainSlides=true;
}
}
drawMapBitmap();
return true;
}
return super.onOptionsItemSelected(mi);
}
public void updateActionBarLabels(){
final SimpleDateFormat simpleDateFormat = Weather.getSimpleDateFormat(Weather.SimpleDateFormats.DATEYEARTIME);
String update = simpleDateFormat.format(WeatherSettings.Updates.getLastUpdate(context,WeatherSettings.Updates.Category.WARNINGS));
if (weatherWarnings!=null){
actionBar.setSubtitle(update+" ("+weatherWarnings.size()+")");
} else {
actionBar.setSubtitle(getApplicationContext().getResources().getString(R.string.warnings_update_fail));
}
}
private void displayWarnings(){
if (weatherWarnings!=null){
runOnUiThread(new Runnable() {
@Override
public void run() {
updateActionBarLabels();
}
});
TextView noWarnings = (TextView) findViewById(R.id.warningactivity_no_warnings);
if (weatherWarnings.size()==0){
noWarnings.setVisibility(View.VISIBLE);
} else {
noWarnings.setVisibility(View.GONE);
}
TextView warningsDeprecated = (TextView) findViewById(R.id.warningactivity_warnings_deprecated);
if (WeatherSettings.Updates.isSyncDue(context,WeatherSettings.Updates.Category.WARNINGS)){
warningsDeprecated.setVisibility(View.VISIBLE);
} else {
warningsDeprecated.setVisibility(View.GONE);
}
}
WeatherWarnings.getWarningsForLocationRunnable getWarningsForLocationRunnable = new WeatherWarnings.getWarningsForLocationRunnable(getApplicationContext(),null,null) {
@Override
public void onResult(ArrayList<WeatherWarning> result) {
localWarnings = result;
runOnUiThread(new Runnable() {
@Override
public void run() {
weatherList = (ListView) findViewById(R.id.warningactivity_listview);
weatherWarningAdapter = new WeatherWarningAdapter(getBaseContext(),weatherWarnings,scheduledExecutorService);
weatherWarningAdapter.setLocalWarnings(localWarnings);
weatherList.setAdapter(weatherWarningAdapter);
weatherList.setSelection(WeatherWarnings.getFirstWarningPosition(weatherWarnings,localWarnings));
weatherList.invalidate();
}
});
}
};
scheduledExecutorService.execute(getWarningsForLocationRunnable);
if (weatherWarnings!=null){
runOnUiThread(new Runnable() {
@Override
public void run() {
displayMap();
}
});
}
}
public static class PlotPoint{
float x;
float y;
}
public PlotPoint getPlotPoint(float lon, float lat){
PlotPoint plotPoint = new PlotPoint();
plotPoint.x = (float) mercatorProjectionTile.getXPixel(lon);
plotPoint.y = (float) mercatorProjectionTile.getYPixel(lat);
return plotPoint;
}
private float getXGeo(PlotPoint plotPoint){
float xCoord = (float) mercatorProjectionTile.getXCoord(plotPoint.x);
return xCoord;
}
private float getYGeo(PlotPoint plotPoint){
float yCoord = (float) mercatorProjectionTile.getYCoord(plotPoint.y);
return yCoord;
}
private void drawStrokedText(Canvas canvas, String text, float x, float y, Paint paint){
Paint strokePaint = new Paint();
strokePaint.setColor(Color.BLACK);
strokePaint.setStyle(Paint.Style.FILL_AND_STROKE);
strokePaint.setTypeface(Typeface.DEFAULT);
strokePaint.setTextSize(paint.getTextSize());
strokePaint.setAntiAlias(true);
int shiftX = Math.max(2,germany.getWidth()/RadarMN2.getFixedRadarMapWidth(context));
int shiftY = Math.max(2,germany.getHeight()/RadarMN2.getFixedRadarMapHeight(context));
canvas.drawText(text,x-shiftX,y,strokePaint);
canvas.drawText(text,x+shiftX,y,strokePaint);
canvas.drawText(text,x,y-shiftY,strokePaint);
canvas.drawText(text,x,y+shiftY,strokePaint);
canvas.drawText(text,x,y,paint);
}
@SuppressLint("NewApi")
private void showRainDescription(){
// Determine the height of the info bar
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
windowManager.getDefaultDisplay().getMetrics(displayMetrics);
int infoBarHeight = displayMetrics.heightPixels/12;
int infoBarWidth = Math.round(displayMetrics.widthPixels*(8f/20f)*(14f/20f));
if (!deviceIsLandscape){
infoBarWidth = Math.round(displayMetrics.widthPixels*(14f/20f));
infoBarHeight = Math.round(displayMetrics.heightPixels*(1/28f)); // less than 30 to account for action bar & system elements at top of screen
}
// this is the result bitmap holding the color bar and the text legend
Bitmap infoBitmap=Bitmap.createBitmap(Math.round(infoBarWidth),Math.round(infoBarHeight), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(infoBitmap);
// this is the color bar, holding 50% of the space
// original bitmap resolution of the info bar is 824x34 pixels
float targetHeightColorBar = infoBarHeight/2f;
float targetWidthColorBar = infoBarWidth;
Bitmap radarinfobarResourceBitmap;
radarinfobarResourceBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),WeatherIcons.getIconResource(getApplicationContext(),WeatherIcons.RADARINFOBAR)),Math.round(targetWidthColorBar),Math.round(targetHeightColorBar),true);
Paint rpaint = new Paint();
rpaint.setStyle(Paint.Style.FILL);
canvas.drawBitmap(radarinfobarResourceBitmap,0,infoBitmap.getHeight()-radarinfobarResourceBitmap.getHeight(),rpaint);
Paint radarTextPaint = new Paint();
radarTextPaint.setTypeface(Typeface.DEFAULT);
radarTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
radarTextPaint.setAntiAlias(true);
radarTextPaint.setFakeBoldText(true);
int textsize = infoBarHeight/2;
radarTextPaint.setTextSize(textsize);
// fix the textsize to prevent overlapping of labels if the total width available is small
String rainRadarLabelText1 = getResources().getString(R.string.radar_rain1);
String rainRadarLabelText2 = getResources().getString(R.string.radar_rain2);
String rainRadarLabelText3 = getResources().getString(R.string.radar_rain3);
String rainRadarLabelText4 = getResources().getString(R.string.radar_rain4);
int widestRadarLabel = 1; String widestRadarLabelText = rainRadarLabelText1;
if (radarTextPaint.measureText(rainRadarLabelText2)>radarTextPaint.measureText(rainRadarLabelText1)){
widestRadarLabel = 2; widestRadarLabelText = rainRadarLabelText2;
}
if (radarTextPaint.measureText(rainRadarLabelText3)>radarTextPaint.measureText(widestRadarLabelText)){
widestRadarLabel = 3; widestRadarLabelText = rainRadarLabelText3;
}
if (radarTextPaint.measureText(rainRadarLabelText4)>radarTextPaint.measureText(widestRadarLabelText)){
widestRadarLabel = 4; widestRadarLabelText = rainRadarLabelText4;
}
int widestLabelWidth = Math.round(radarTextPaint.measureText(widestRadarLabelText));
while ((textsize>6) && (infoBarWidth-(radarTextPaint.measureText(widestRadarLabelText)*6)<1)){
textsize--;
radarTextPaint.setTextSize(textsize);
}
radarTextPaint.setColor(Color.WHITE);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());
Date rainSlideDate = new Date(rainSlidesStartTime+(nextRainSlide)*APIReaders.RadarMNSetGeoserverRunnable.TIMESTEP_5MINUTES);
String radartime = simpleDateFormat.format(rainSlideDate);
float ff=1.1f;
if (validSlideSetObtained) {
rainSlideTime.setTextColor(Color.WHITE);
if (Calendar.getInstance().getTimeInMillis() > rainSlidesStartTime + +1000*60*60*1.5f){
rainSlideTime.setTextColor(0xfffa7712);
}
} else {
rainSlideTime.setTextColor(Color.YELLOW);
}
rainSlideTime.setText(radartime);
radarTextPaint.setColor(Radarmap.RAINCOLORS[2]);
drawStrokedText(canvas,getResources().getString(R.string.radar_rain1),infoBarWidth*0.1f,infoBitmap.getHeight()-radarinfobarResourceBitmap.getHeight()*ff,radarTextPaint);
radarTextPaint.setColor(Radarmap.RAINCOLORS[7]);
drawStrokedText(canvas,getResources().getString(R.string.radar_rain2),infoBarWidth*0.3f,infoBitmap.getHeight()-radarinfobarResourceBitmap.getHeight(),radarTextPaint);
radarTextPaint.setColor(Radarmap.RAINCOLORS[11]);
drawStrokedText(canvas,getResources().getString(R.string.radar_rain3),infoBarWidth*0.6f,infoBitmap.getHeight()-radarinfobarResourceBitmap.getHeight(),radarTextPaint);
radarTextPaint.setColor(Radarmap.RAINCOLORS[16]);
drawStrokedText(canvas,getResources().getString(R.string.radar_rain4),infoBarWidth*0.8f,infoBitmap.getHeight()-radarinfobarResourceBitmap.getHeight(),radarTextPaint);
if (rainDescription!=null){
rainDescription.setImageBitmap(infoBitmap);
}
}
private void clearRainDescription(){
if (rainDescription==null){
rainDescription = (ImageView) findViewById(R.id.warningactivity_mapinfo);
}
if (rainDescription!=null){
rainDescription.setImageDrawable(null);
}
}
private Bitmap loadBitmapMap(int res_id){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),res_id),RadarMN2.getFixedRadarMapWidth(context),RadarMN2.getFixedRadarMapHeight(context),false);
return bitmap;
}
private void updateRainSlideProgressBar(final int progress){
runOnUiThread(new Runnable() {
@Override
public void run() {
rainSlideProgressBar.setVisibility(View.VISIBLE);
rainSlideProgressBar.setProgress(progress);
rainSlideProgressBar.invalidate();
rainSlideProgressBarText.setVisibility(View.VISIBLE);
rainSlideProgressBarText.setText(Math.round((float) progress/(float) (APIReaders.RadarMNSetGeoserverRunnable.DATASET_SIZE-1)*100f)+"%");
rainSlideProgressBarText.invalidate();
}
});
}
private void drawRadarSlide(final int count){
if (APIReaders.RadarMNSetGeoserverRunnable.radarCacheFileValid(context,count)) {
radarBitmap.eraseColor(Color.TRANSPARENT);
Canvas radarCanvas = new Canvas(radarBitmap);
Bitmap slideBitmap = RadarMN2.getScaledBitmap(context,count);
final Paint radarPaint = new Paint();
radarPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
if (slideBitmap!=null){
radarCanvas.drawBitmap(slideBitmap,0,0,radarPaint);
}
if (!hide_rain) {
drawMapBitmap();
}
} else {
// nothing to do
}
lastDrawnRainSlide=count;
}
private void drawMapBitmap(){
visibleBitmap = germanyBitmap.copy(Bitmap.Config.ARGB_8888,true);
Canvas canvas = new Canvas(visibleBitmap);
final Paint cp = new Paint();
cp.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
canvas.drawBitmap(warningsBitmap,0,0,cp);
if ((!hide_admin)){
if (administrativeBitmap==null){
administrativeBitmap = getAdministrativeBitmap(context,germanyBitmap.getWidth(),germanyBitmap.getHeight(),WeatherSettings.getAreaTypeArray(context));
}
cp.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
canvas.drawBitmap(administrativeBitmap,0,0,cp);
}
if ((!hide_rain) && (radarBitmap!=null)){
cp.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
canvas.drawBitmap(radarBitmap, 0,0,cp);
runOnUiThread(new Runnable() {
@Override
public void run() {
showRainDescription();
}
});
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
clearRainDescription();
}
});
}
mapZoomable.updateBitmap(visibleBitmap);
visibleBitmap.recycle();
}
private void drawWindIcon(){
final Context context = getApplicationContext();
final ImageView windicon = (ImageView) findViewById(R.id.warningactivity_windicon);
Runnable windRunnable = new Runnable() {
@Override
public void run() {
final RelativeLayout windiconContainer = (RelativeLayout) findViewById(R.id.warningactivity_windicon_container);
if (windiconContainer!=null){
if (WeatherSettings.displayWindInRadar(getApplicationContext())){
windiconContainer.setVisibility(View.VISIBLE);
final ImageView windiconBackground = (ImageView) findViewById(R.id.warningactivity_windicon_background);
CurrentWeatherInfo currentWeatherInfo = Weather.getCurrentWeatherInfo(context);
if (currentWeatherInfo!=null){
final Bitmap windiconBitmap = currentWeatherInfo.currentWeather.getWindSymbol(getApplicationContext(),WeatherSettings.getWindDisplayType(getApplicationContext()),false);
ThemePicker.applyColor(context,windiconBitmap,false);
runOnUiThread(new Runnable() {
@Override
public void run() {
windiconBackground.setImageResource(R.drawable.blue);
windiconBackground.setColorFilter(ThemePicker.getColorPrimary(context),PorterDuff.Mode.SRC_IN);
windicon.setImageBitmap(windiconBitmap);
}
});
}
} else {
runOnUiThread(new Runnable() {
@Override
public void run() {
windiconContainer.setVisibility(View.INVISIBLE);
}
});
}
}
}
};
scheduledExecutorService.execute(windRunnable);
}
private boolean hideMap(){
germany.setVisibility(View.GONE);
germany.invalidate();
LinearLayout.LayoutParams rllp = (LinearLayout.LayoutParams) mapcontainer.getLayoutParams();
rllp.height=0;
rllp.weight=0;
mapcontainer.setLayoutParams(rllp);
mapcontainer.invalidate();
mapcontainer.setVisibility(View.GONE);
LinearLayout.LayoutParams mclp = (LinearLayout.LayoutParams) map_collapsed_container.getLayoutParams();
map_collapsed_container.setVisibility(View.VISIBLE);
mclp.weight=1;
map_collapsed_container.setLayoutParams(mclp);
map_collapsed_container.invalidate();
LinearLayout.LayoutParams lop = (LinearLayout.LayoutParams) weatherList.getLayoutParams();
lop.weight=29;
weatherList.setLayoutParams(lop);
weatherList.invalidate();
LinearLayout.LayoutParams infoContLop = (LinearLayout.LayoutParams) warningactivityMapinfoContainer.getLayoutParams();
infoContLop.weight=0;
return true;
}
private boolean showMap(){
germany.setVisibility(View.VISIBLE);
mapcontainer.setVisibility(View.VISIBLE);
LinearLayout.LayoutParams rllp = (LinearLayout.LayoutParams) mapcontainer.getLayoutParams();
rllp.height=0;
rllp.weight=18;
mapcontainer.setLayoutParams(rllp);
mapcontainer.invalidate();
LinearLayout.LayoutParams mclp = (LinearLayout.LayoutParams) map_collapsed_container.getLayoutParams();
mclp.height=0;
mclp.weight=0;
map_collapsed_container.setLayoutParams(mclp);
map_collapsed_container.invalidate();
map_collapsed_container.setVisibility(View.GONE);
LinearLayout.LayoutParams lop = (LinearLayout.LayoutParams) weatherList.getLayoutParams();
lop.height=0;
lop.weight=11;
weatherList.setLayoutParams(lop);
weatherList.invalidate();
LinearLayout.LayoutParams infoContLop = (LinearLayout.LayoutParams) warningactivityMapinfoContainer.getLayoutParams();
infoContLop.weight=1;
return true;
}
private void displayMap(){
germanyBitmap = loadBitmapMap(WeatherIcons.getIconResource(getApplicationContext(),WeatherIcons.GERMANY));
warningsBitmap = Bitmap.createBitmap(germanyBitmap.getWidth(),germanyBitmap.getHeight(), Bitmap.Config.ARGB_8888);
warningsBitmap.eraseColor(Color.TRANSPARENT);
radarBitmap = Bitmap.createBitmap(germanyBitmap.getWidth(),germanyBitmap.getHeight(), Bitmap.Config.ARGB_8888);
radarBitmap.eraseColor(Color.TRANSPARENT);
MAP_PIXEL_HEIGHT = warningsBitmap.getHeight();
MAP_PIXEL_WIDTH = warningsBitmap.getWidth();
polygoncache = new ArrayList<Polygon>();
excluded_polygoncache = new ArrayList<Polygon>();
final Canvas canvas = new Canvas(warningsBitmap);
ArrayList<WeatherWarning> drawWarnings = (ArrayList<WeatherWarning>) weatherWarnings.clone();
Collections.sort(drawWarnings);
Collections.reverse(drawWarnings);
for (int warning_counter=0; warning_counter<drawWarnings.size(); warning_counter++){
WeatherWarning warning = drawWarnings.get(warning_counter);
for (int polygon_counter=0; polygon_counter<warning.polygonlist.size(); polygon_counter++){
float[] polygonX = warning.polygonlist.get(polygon_counter).polygonX;
float[] polygonY = warning.polygonlist.get(polygon_counter).polygonY;
// add polygon to cache
polygoncache.add(new Polygon(polygonX,polygonY,warning.identifier));
if (polygonX.length>0){
Path path = new Path();
PlotPoint plotPoint = getPlotPoint(polygonX[0],polygonY[0]);
path.moveTo(plotPoint.x, plotPoint.y);
for (int vertex_count=1; vertex_count<polygonX.length; vertex_count++){
plotPoint = getPlotPoint(polygonX[vertex_count],polygonY[vertex_count]);
path.lineTo(plotPoint.x, plotPoint.y);
}
Paint polypaint = new Paint();
polypaint.setColor(warning.getWarningColor());
polypaint.setAlpha(128);
polypaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path,polypaint);
}
}
// draw black excluded polygons after other polygons were drawn
for (int polygon_counter=0; polygon_counter<warning.excluded_polygonlist.size(); polygon_counter++){
float[] polygonX = warning.excluded_polygonlist.get(polygon_counter).polygonX;
float[] polygonY = warning.excluded_polygonlist.get(polygon_counter).polygonY;
// add excluded-polygon to cache
excluded_polygoncache.add(new Polygon(polygonX,polygonY,warning.identifier));
if (polygonX.length>0){
Path path = new Path();
PlotPoint plotPoint = getPlotPoint(polygonX[0],polygonY[0]);
path.moveTo(plotPoint.x,plotPoint.y);
for (int vertex_count=1; vertex_count<polygonX.length; vertex_count++){
plotPoint = getPlotPoint(polygonX[vertex_count],polygonY[vertex_count]);
path.lineTo(plotPoint.x,plotPoint.y);
}
Paint polypaint = new Paint();
Color color = new Color();
polypaint.setColor(Color.TRANSPARENT);
polypaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawPath(path,polypaint);
}
}
}
drawWindIcon();
// set close listener
ImageView closeImageview = (ImageView) findViewById(R.id.closeicon_map);
if (closeImageview != null){
closeImageview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return hideMap();
}
});
}
// set listener
germany = (ImageView) findViewById(R.id.warningactivity_map);
gestureDetector = new GestureDetector(this,new MapGestureListener());
//mapZoomable = new ZoomableImageView(getApplicationContext(),germany,germanyBitmap) {
mapZoomable = new ZoomableImageView(getApplicationContext(),germany,warningsBitmap){
@Override
public void onGestureFinished(float scaleFactor, float lastXtouch, float lastYtouch, float xFocus, float yFocus, float xFocusRelative, float yFocusRelative, RectF currentlyVisibleArea){
final PlotPoint plotPoint = new PlotPoint();
plotPoint.x = lastXtouch;
plotPoint.y = lastYtouch;
Runnable tapRunnable = new Runnable() {
@Override
public void run() {
checkForTapInPolygonWarning(getXGeo(plotPoint),getYGeo(plotPoint));
}
};
scheduledExecutorService.execute(tapRunnable);
}
};
if (RadarMN2.getScaleFactor(context)>1){
mapZoomable.setScaleRange(0.12f,1f);
}
if (zoomMapState!=null){
mapZoomable.restoreZoomViewState(zoomMapState);
}
drawMapBitmap();
// add the pin sprite
float pinSize = WeatherSettings.getMapPinSize(context)/2f;
if (pinSize>0){
int pinSizePixels = Math.round(18*this.getApplicationContext().getResources().getDisplayMetrics().density*pinSize);
PlotPoint pinPoint = getPlotPoint((float) ownLocation.longitude, (float) ownLocation.latitude);
Bitmap pinBitmap = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),R.mipmap.pin),pinSizePixels,pinSizePixels,false);
mapZoomable.addSpite(pinBitmap,pinPoint.x,pinPoint.y-pinBitmap.getHeight(),ZoomableImageView.SPRITEFIXPOINT.BOTTOM_LEFT,null);
}
mapZoomable.redrawBitmap();
mapTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mapZoomable.onTouchEvent(motionEvent);
return true;
};
};
germany.setOnTouchListener(mapTouchListener);
}
class MapGestureListener extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onSingleTapUp(MotionEvent e) {
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public void onShowPress(MotionEvent e) {
super.onShowPress(e);
}
@Override
public boolean onDown(MotionEvent e)
{
// catch collapse-button-press prior to map-selection
// perform this only if NOT in landscape layout
if ((!deviceIsLandscape) && (map_collapsed_container!=null) && (germany!=null) && (weatherList!=null)){
float button_border_right = (float) (germany.getMeasuredWidth() * 0.127427184);
float button_border_bottom = (float) (germany.getMeasuredHeight() * 0.10041841);
if ((e.getX()<button_border_right) && (e.getY()<button_border_bottom)){
return hideMap();
}
}
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return super.onDoubleTap(e);
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return super.onDoubleTapEvent(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return super.onSingleTapConfirmed(e);
}
@Override
public boolean onContextClick(MotionEvent e) {
return super.onContextClick(e);
}
}
private void checkForTapInPolygonWarning(float x_geo, float y_geo){
if (polygoncache!=null){
int position = 0;
// first check if pointer is in excluded polygon; it is more efficient to do this first.
if (excluded_polygoncache!=null){
while (position<excluded_polygoncache.size()){
if (excluded_polygoncache.get(position).isInPolygon(x_geo,y_geo)){
// break (& do nothing) if pointer is in excluded polygon.
return;
}
position++;
}
}
position = 0;
while (position<polygoncache.size()){
if (polygoncache.get(position).isInPolygon(x_geo,y_geo)){
jumpListViewToSelection(polygoncache.get(position));
return;
}
position++;
}
}
}
private void jumpListViewToSelection(Polygon polygon){
int position=0;
while (position<weatherWarnings.size()){
if (weatherWarnings.get(position).identifier.equals(polygon.identifier_link)){
break;
}
position++;
}
if (weatherList != null){
final int jumpPosition = position;
runOnUiThread(new Runnable() {
@Override
public void run() {
weatherList.setSelection(jumpPosition);
}
});
}
}
private boolean isDeviceLandscape(){
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getRotation();
if ((orientation==Surface.ROTATION_0)|| (orientation==Surface.ROTATION_180)){
return false;
}
return true;
}
private void showProgressBar(){
runOnUiThread(new Runnable() {
@Override
public void run() {
ProgressBar progressBar = (ProgressBar) findViewById(R.id.warningactivity_progressbar);
if (progressBar!=null){
progressBar.setVisibility(View.VISIBLE);
}
}
});
}
private void hideProgressBar(){
runOnUiThread(new Runnable() {
@Override
public void run() {
ProgressBar progressBar = (ProgressBar) findViewById(R.id.warningactivity_progressbar);
if (progressBar!=null){
progressBar.setVisibility(View.INVISIBLE);
}
}
});
}
private void registerForBroadcast(){
IntentFilter filter = new IntentFilter();
filter.addAction(WEATHER_WARNINGS_UPDATE);
filter.addAction(MainActivity.MAINAPP_HIDE_PROGRESS);
filter.addAction(ACTION_RAINRADAR_UPDATE);
registerReceiver(receiver,filter);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int permRequestCode, String perms[], int[] grantRes){
Boolean hasLocationPermission = false;
for (int i=0; i<grantRes.length; i++){
if ((perms[i].equals(Manifest.permission.ACCESS_FINE_LOCATION)) && (grantRes[i]== PackageManager.PERMISSION_GRANTED)){
hasLocationPermission = true;
}
}
if (permRequestCode == WeatherLocationManager.PERMISSION_CALLBACK_LOCATION){
if (hasLocationPermission){
if (weatherLocationManager!=null){
weatherLocationManager.checkLocation();
}
} else {
if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){
showLocationPermissionsRationale();
}
}
}
}
private void showSimpleLocationAlert(String text){
AlertDialog.Builder builder = new AlertDialog.Builder(this,0);
builder.setTitle(getApplicationContext().getResources().getString(R.string.geoinput_title));
Drawable drawable = new BitmapDrawable(getResources(),WeatherIcons.getIconBitmap(context,WeatherIcons.IC_GPS_FIXED,false));
builder.setIcon(drawable);
builder.setMessage(text);
builder.setPositiveButton(R.string.alertdialog_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void showLocationPermissionsRationale(){
showSimpleLocationAlert(getApplicationContext().getResources().getString(R.string.geoinput_rationale));
}
public Bitmap getAdministrativeBitmap(Context context, int targetWidth, int targetHeight, int[] types){
Bitmap resultBitmap = Bitmap.createBitmap(targetWidth,targetHeight, Bitmap.Config.ARGB_8888);
resultBitmap.eraseColor(Color.TRANSPARENT);
Canvas canvas = new Canvas(resultBitmap);
for (int type=0; type<types.length; type++){
ArrayList<Areas.Area> allAreas = Areas.getAreas(context, types[type]);
Paint areaPaint = new Paint();
areaPaint.setColor(Color.BLACK);
areaPaint.setAlpha(96);
areaPaint.setStyle(Paint.Style.STROKE);
if (types[type]==Areas.Area.Type.SEE){
areaPaint.setColor(Color.CYAN);
}
if (types[type]==Areas.Area.Type.KUESTE){
areaPaint.setColor(Color.YELLOW);
}
if (types[type]==Areas.Area.Type.GEMEINDE){
areaPaint.setColor(Color.GRAY);
}
if (types[type]==Areas.Area.Type.BUNDESLAND){
areaPaint.setColor(Color.BLUE);
areaPaint.setStrokeWidth(2);
}
for (int i=0; i<allAreas.size(); i++){
Areas.Area cellArea = allAreas.get(i);
ArrayList<Polygon> areaPolygons = cellArea.polygons;
for (int p=0; p<areaPolygons.size(); p++){
Polygon areaPolygon = areaPolygons.get(p);
Path path = new Path();
PlotPoint plotPoint = getPlotPoint(areaPolygon.polygonX[0],areaPolygon.polygonY[0]);
path.moveTo(plotPoint.x, plotPoint.y);
for (int v=0; v<areaPolygon.polygonX.length; v++){
plotPoint = getPlotPoint(areaPolygon.polygonX[v],areaPolygon.polygonY[v]);
path.lineTo(plotPoint.x, plotPoint.y);
}
canvas.drawPath(path,areaPaint);
}
}
}
return resultBitmap;
}
public void popupHint(){
final int[] hintTimes = {20,3,6,9};
final int count = WeatherSettings.getHintCounter2(context);
if ((count==hintTimes[1]) || (count==hintTimes[2]) || (count==hintTimes[3])){
final RelativeLayout anchorView = (RelativeLayout) findViewById(R.id.warningactivity_main_relative_container);
if (anchorView!=null){
anchorView.post(new Runnable() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int displayWidth = Math.round(displayMetrics.widthPixels);
int displayHeight = Math.round(displayMetrics.heightPixels);
final boolean isLandscape = displayWidth>displayHeight;
LayoutInflater layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.popup_hint1,null);
// set correct theme textcolors
TextView textView1 = (TextView) popupView.findViewById(R.id.hint1_text);
textView1.setTextColor(Color.WHITE);
// register click callbacks
Button bottonOk = (Button) popupView.findViewById(R.id.hint1_button);
bottonOk.setTextColor(Color.WHITE);
bottonOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (hintPopupWindow!=null){
hintPopupWindow.dismiss();
}
}
});
CheckBox checkNo = (CheckBox) popupView.findViewById(R.id.hint1_checkbox);
checkNo.setTextColor(Color.WHITE);
checkNo.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
if (checked){
WeatherSettings.setHintCounter1(context,hintTimes[0]);
WeatherSettings.setHintCounter2(context,hintTimes[0]);
} else {
WeatherSettings.setHintCounter1(context,0);
WeatherSettings.setHintCounter2(context,0);
}
}
});
int width = Math.round(displayWidth * 0.8f);
int height = Math.round(displayHeight * 0.26f);
if (isLandscape){
height = Math.round(displayHeight * 0.4f);
}
ImageView imageView = (ImageView) popupView.findViewById(R.id.hint1_image);
if (count==hintTimes[1]){
textView1.setText(context.getResources().getString(R.string.hint_1));
imageView.setImageResource(R.drawable.radar_hint);
height = Math.round(displayHeight * 0.47f);
if (isLandscape){
height = Math.round(displayHeight * 0.6f);
}
}
if (count==hintTimes[2]){
textView1.setText(context.getResources().getString(R.string.welcome_s3_text1));
imageView.setImageResource(R.drawable.collapse_hint);
}
if (count==hintTimes[3]){
textView1.setText(context.getResources().getString(R.string.welcome_s3_text2));
imageView.setImageResource(R.drawable.expand_hint);
}
hintPopupWindow = new PopupWindow(popupView,width,height,true);
hintPopupWindow.showAtLocation(anchorView,Gravity.CENTER,0,0);
}
});
}
});
}
}
if (count<hintTimes[0]){
int newCount = count + 1;
WeatherSettings.setHintCounter2(context,newCount);
}
}
}