マップ オーバーレイとして表示される米国全体の気温のビットマップがあります。その部分は正常に機能します。ビットマップ温度オーバーレイは、境界線と地理的ポイントに対してマップ上に完全に配置されます.
私の目標は、この温度ビットマップをタップして、そのピクセルの色に基づいて温度を出力できるようにすることです。ビットマップ オーバーレイは、現在の地図投影に基づいてスケーリングおよび配置されています。タップされたときにビットマップ ピクセルを取得するための私の解決策では、ジオポイントを使用して逆戻りし、スケーリングを考慮してから、元のビットマップ イメージからタップされたポイントを取得する必要があります。
タッピングは正常に機能しますが、どのピクセルが取得されるかについては不正確であることに気付きました。たとえば、ビットマップの可視部分の下をタップしても (メキシコのように)、色付きのピクセルを返すことができます. これは、返されたピクセル値がすべて南に約 50 マイルずれているようなものです。ズームアウトすると、エラーは大きくも明白でもありませんが、ズームインすると、明らかに間違ったピクセル (温度) 値が返されるため、明らかになります。
私の方法は健全だと思いますが、私が扱っている大きな数が「倍精度」で問題を引き起こしているのではないかと思っています。BigDecimal (経験なし) またはその他の数値形式に切り替える必要がありますか? これを行うより良い方法はありますか?
以下のコード>>>>
public class BitmapOverlay extends Overlay {
Bitmap bmp;
Bitmap bmp2;
Context mContext;
GeoPoint upperLeft;
GeoPoint lowerRight;
Paint paint;
Paint lpaint;
Point ppupperLeft;
Point pplowerRight;
Rect src;
Rect src2;
Rect dst;
int frame;
int complete=100;
boolean shadow;
AnimationDrawable animation;
ImageView radarView;
Double W=(-129.357400913)* 1E6;
Double S=(23.560962423770285)* 1E6;
Double E=(-64.6787004566)* 1E6;
Double N=(50.3092170302897)* 1E6;
Projection currentProjection;
boolean mExternalStorageAvailable = false;
String fullPath;
boolean running;
public BitmapOverlay (Context freshContext){
paint = new Paint(Paint.FILTER_BITMAP_FLAG);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = true;
Log.i("isSdReadable", "External storage card is readable.");
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
Log.i("isSdReadable", "External storage card is readable.");
mExternalStorageAvailable = true;
} else {
// Something else is wrong. It may be one of many other
// states, but all we need to know is we can neither read nor write
mExternalStorageAvailable = false;
}
upperLeft=new GeoPoint(N.intValue(),W.intValue());
lowerRight=new GeoPoint(S.intValue(),E.intValue());
ppupperLeft = new Point();
pplowerRight = new Point();
mContext=freshContext;
}
public void UpdateFrame(int sentframe , String ET){
frame=sentframe;
// complete=sentcomplete;
if ( mExternalStorageAvailable == true) {
// Log.i("MyRadarOverlay", "got BMP Frame="+frame);
//have to convert complete to frame to sequence... otherwise it gets to 5
and stops..
//might need to figure better wayt o tell when bmp is done
//complete=frame-1;
if (ET.equals("temp")){fullPath =
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Pictures/ti0.png";}
if (ET.equals("radar")){fullPath =
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Pictures/ri"+frame+".png";}
// Look for the file on the external storage
try {
bmp = BitmapFactory.decodeFile(fullPath);
//}
} catch (Exception e) {
Log.e("getThumbnail() on external storage", e.getMessage());
}
if (ET.equals("radar")){
fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/Pictures/si"+frame+".png";
// Log.i("MyRadarOverlay", "sifile path="+fullPath);
// Look for the file on the external storage
try {
//if (tools.isSdReadable() == true) {
bmp2 = BitmapFactory.decodeFile(fullPath);
//}
} catch (Exception e) {
Log.e("getThumbnail() on external storage", e.getMessage());
}
//end of second if et == radar
}
}
}
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
currentProjection=mapView.getProjection();
currentProjection.toPixels(upperLeft, ppupperLeft);
currentProjection.toPixels(lowerRight, pplowerRight);
dst = new Rect( ppupperLeft.x, ppupperLeft.y, pplowerRight.x, pplowerRight.y );
if (bmp2 != null ){
src = new Rect( 0,0, bmp2.getWidth() , bmp2.getHeight() );
canvas.drawBitmap(bmp2, src, dst, paint);
}
if (bmp != null ){
src = new Rect( 0,0, bmp.getWidth() , bmp.getHeight() );
canvas.drawBitmap(bmp, src, dst, paint);
}
}
//###################ON TAP#################################
@Override
public boolean onTap( GeoPoint geoPoint, MapView mapView) {
// Log.i("My Info", "overlay-on tap called");
Log.i("BITMAP OVERALY", "TAP at"+geoPoint);
// take left lon add right lon...add basically get a range of lons that the point can
fall under//
// if it falls within the range get the percentage ...
// the start left most lon is equivalent to 0 the right most is equavalent to the
width--1600
// find the relative position on that range
double xpixel=0;
double ypixel=0;
double latgeopoint=geoPoint.getLatitudeE6();
double longeopoint=geoPoint.getLongitudeE6();
//find out if it is within longitude range of bitmap
if (longeopoint>W && longeopoint<E){
//find out if it is within latitude range of bitmap
if (latgeopoint>S && latgeopoint<N){
Log.i("BITMAP OVERALY", "passed if statement-
lon,lat"+longeopoint+","+latgeopoint);
//work on lon side
double lonrange=W-longeopoint;
Log.i("BITMAP OVERALY", "lonrange="+lonrange);
//-64678700456
double lonratio=lonrange/W-E;
Log.i("BITMAP OVERALY", "lonratio="+lonratio);
xpixel=lonratio*bmp.getWidth();
Log.i("BITMAP OVERALY", "xpixel="+xpixel);
//work on lat side
double latrange=N-latgeopoint;
Log.i("BITMAP OVERALY", "latrange="+latrange);
//26748254607
double latratio=latrange/N-S;
Log.i("BITMAP OVERALY", "latratio="+latratio);
ypixel=latratio*bmp.getHeight();
Log.i("BITMAP OVERALY", "ypixel="+ypixel);
//end if lat
}
//end if lon
}
//convert doubles to ints
int pixelx = (int)xpixel;
int pixely = (int)ypixel;
Log.i("BITMAP OVERALY", "pixelx,pixely="+pixelx+","+pixely);
int pixel = bmp.getPixel(pixelx, pixely);
int redValue = Color.red(pixel);
int greenValue = Color.green(pixel);
int blueValue = Color.blue(pixel);
float[] hsv = new float[3];
Color.RGBToHSV(redValue, greenValue, blueValue, hsv);
String mytemp="";
if (hsv[0]<5){mytemp="Greater than 110";}
if (hsv[0]<=20 && hsv[0]>5){mytemp="100 to 110";}
if (hsv[0]<=45 && hsv[0]>20){mytemp="90 to 100";}
if (hsv[0]<=60 && hsv[0]>45){mytemp="80 to 90";}
if (hsv[0]<=80 && hsv[0]>60){mytemp="70 to 80";}
if (hsv[0]<=120 && hsv[0]>80){mytemp="60 to 70";}
if (hsv[0]<=150 && hsv[0]>120){mytemp="50 to 60";}
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setNegativeButton("Close",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
dialog.setTitle("BITMAP TAP hsv=" + hsv[0] + " " + hsv[1] + " " +
hsv[2] + " TEMP="+mytemp);
dialog.show();
return false;
//end on tap
}
}