Blackberry 是否有Math.atan2替代j2ME?黑莓开发
我的持久对象中存储了各种各样的位置,包含双(43.7389,7.42577)格式的纬度和经度。我需要能够抓住用户的纬度和经度,并选择范围内的所有项目,比如说1英里。步行距离。 我已经在PHP中完成了这项工作,所以我将PHP代码挂起,并将其传输到Java,在Java中,一切都可以正常插入,直到我发现J2ME不支持atan2(double,double)。所以,经过一些搜索,我找到了一个小代码片段,它应该是atan2的替代品。代码如下:Blackberry 是否有Math.atan2替代j2ME?黑莓开发,blackberry,gps,atan2,Blackberry,Gps,Atan2,我的持久对象中存储了各种各样的位置,包含双(43.7389,7.42577)格式的纬度和经度。我需要能够抓住用户的纬度和经度,并选择范围内的所有项目,比如说1英里。步行距离。 我已经在PHP中完成了这项工作,所以我将PHP代码挂起,并将其传输到Java,在Java中,一切都可以正常插入,直到我发现J2ME不支持atan2(double,double)。所以,经过一些搜索,我找到了一个小代码片段,它应该是atan2的替代品。代码如下: public double atan2(double y, d
public double atan2(double y, double x) {
double coeff_1 = Math.PI / 4d;
double coeff_2 = 3d * coeff_1;
double abs_y = Math.abs(y)+ 1e-10f;
double r, angle;
if (x >= 0d) {
r = (x - abs_y) / (x + abs_y);
angle = coeff_1;
} else {
r = (x + abs_y) / (abs_y - x);
angle = coeff_2;
}
angle += (0.1963f * r * r - 0.9817f) * r;
return y < 0.0f ? -angle : angle;
}
public-double-atan2(双y,双x){
双系数_1=Math.PI/4d;
双系数2=3d*coeff_1;
双abs_y=数学abs(y)+1e-10f;
双r角;
如果(x>=0d){
r=(x-绝对值y)/(x+绝对值y);
角度=系数1;
}否则{
r=(x+abs_y)/(abs_y-x);
角度=系数2;
}
角度+=(0.1963f*r*r-0.9817f)*r;
返回y<0.0f?角度:角度;
}
我从中得到了奇怪的结果。我的最小和最大纬度和经度都是难以置信的低值,不可能是正确的。比如0.003785746,当我期望接近原始lat和long值(43.7389,7.42577)时
因为我不是高等数学硕士,我真的不知道在这里找什么。也许其他人会有答案
这是我的完整代码:
package store_finder;
import java.util.Vector;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;
import javax.microedition.location.QualifiedCoordinates;
import net.rim.blackberry.api.invoke.Invoke;
import net.rim.blackberry.api.invoke.MapsArguments;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.RichTextField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.HorizontalFieldManager;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;
public class nearBy extends MainScreen {
private HorizontalFieldManager _top;
private VerticalFieldManager _middle;
private int horizontalOffset;
private final static long animationTime = 300;
private long animationStart = 0;
private double latitude = 43.7389;
private double longitude = 7.42577;
private int _interval = -1;
private double max_lat;
private double min_lat;
private double max_lon;
private double min_lon;
private double latitude_in_degrees;
private double longitude_in_degrees;
public nearBy()
{
super();
horizontalOffset = Display.getWidth();
_top = new HorizontalFieldManager(Manager.USE_ALL_WIDTH | Field.FIELD_HCENTER)
{
public void paint(Graphics gr)
{
Bitmap bg = Bitmap.getBitmapResource("bg.png");
gr.drawBitmap(0, 0, Display.getWidth(), Display.getHeight(), bg, 0, 0);
subpaint(gr);
}
};
_middle = new VerticalFieldManager()
{
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(0xFFFFFF);
graphics.setColor(Color.BLACK);
graphics.clear();
super.paint(graphics);
}
protected void sublayout(int maxWidth, int maxHeight)
{
int displayWidth = Display.getWidth();
int displayHeight = Display.getHeight();
super.sublayout( displayWidth, displayHeight);
setExtent( displayWidth, displayHeight);
}
};
add(_top);
add(_middle);
Bitmap lol = Bitmap.getBitmapResource("logo.png");
BitmapField lolfield = new BitmapField(lol);
_top.add(lolfield);
Criteria cr= new Criteria();
cr.setCostAllowed(true);
cr.setPreferredResponseTime(60);
cr.setHorizontalAccuracy(5000);
cr.setVerticalAccuracy(5000);
cr.setAltitudeRequired(true);
cr.isSpeedAndCourseRequired();
cr.isAddressInfoRequired();
try{
LocationProvider lp = LocationProvider.getInstance(cr);
if( lp!=null ){
lp.setLocationListener(new LocationListenerImpl(), _interval, 1, 1);
}
}
catch(LocationException le)
{
add(new RichTextField("Location exception "+le));
}
//_middle.add(new RichTextField("this is a map " + Double.toString(latitude) + " " + Double.toString(longitude)));
int lat = (int) (latitude * 100000);
int lon = (int) (longitude * 100000);
String document = "<location-document>" + "<location lon='" + lon + "' lat='" + lat + "' label='You are here' description='You' zoom='0' />" + "<location lon='742733' lat='4373930' label='Hotel de Paris' description='Hotel de Paris' address='Palace du Casino' postalCode='98000' phone='37798063000' zoom='0' />" + "</location-document>";
// Invoke.invokeApplication(Invoke.APP_TYPE_MAPS, new MapsArguments( MapsArguments.ARG_LOCATION_DOCUMENT, document));
_middle.add(new SeparatorField());
surroundingVenues();
_middle.add(new RichTextField("max lat: " + max_lat));
_middle.add(new RichTextField("min lat: " + min_lat));
_middle.add(new RichTextField("max lon: " + max_lon));
_middle.add(new RichTextField("min lon: " + min_lon));
}
private void surroundingVenues()
{
double point_1_latitude_in_degrees = latitude;
double point_1_longitude_in_degrees= longitude;
// diagonal distance + error margin
double distance_in_miles = (5 * 1.90359441) + 10;
getCords (point_1_latitude_in_degrees, point_1_longitude_in_degrees, distance_in_miles, 45);
double lat_limit_1 = latitude_in_degrees;
double lon_limit_1 = longitude_in_degrees;
getCords (point_1_latitude_in_degrees, point_1_longitude_in_degrees, distance_in_miles, 135);
double lat_limit_2 = latitude_in_degrees;
double lon_limit_2 = longitude_in_degrees;
getCords (point_1_latitude_in_degrees, point_1_longitude_in_degrees, distance_in_miles, -135);
double lat_limit_3 = latitude_in_degrees;
double lon_limit_3 = longitude_in_degrees;
getCords (point_1_latitude_in_degrees, point_1_longitude_in_degrees, distance_in_miles, -45);
double lat_limit_4 = latitude_in_degrees;
double lon_limit_4 = longitude_in_degrees;
double mx1 = Math.max(lat_limit_1, lat_limit_2);
double mx2 = Math.max(lat_limit_3, lat_limit_4);
max_lat = Math.max(mx1, mx2);
double mm1 = Math.min(lat_limit_1, lat_limit_2);
double mm2 = Math.min(lat_limit_3, lat_limit_4);
min_lat = Math.max(mm1, mm2);
double mlon1 = Math.max(lon_limit_1, lon_limit_2);
double mlon2 = Math.max(lon_limit_3, lon_limit_4);
max_lon = Math.max(mlon1, mlon2);
double minl1 = Math.min(lon_limit_1, lon_limit_2);
double minl2 = Math.min(lon_limit_3, lon_limit_4);
min_lon = Math.max(minl1, minl2);
//$qry = "SELECT DISTINCT zip.zipcode, zip.latitude, zip.longitude, sg_stores.* FROM zip JOIN store_finder AS sg_stores ON sg_stores.zip=zip.zipcode WHERE zip.latitude<=$lat_limit_max AND zip.latitude>=$lat_limit_min AND zip.longitude<=$lon_limit_max AND zip.longitude>=$lon_limit_min";
}
private void getCords(double point_1_latitude, double point_1_longitude, double distance, int degs)
{
double m_EquatorialRadiusInMeters = 6366564.86;
double m_Flattening=0;
double distance_in_meters = distance * 1609.344 ;
double direction_in_radians = Math.toRadians( degs );
double eps = 0.000000000000005;
double r = 1.0 - m_Flattening;
double point_1_latitude_in_radians = Math.toRadians( point_1_latitude );
double point_1_longitude_in_radians = Math.toRadians( point_1_longitude );
double tangent_u = (r * Math.sin( point_1_latitude_in_radians ) ) / Math.cos( point_1_latitude_in_radians );
double sine_of_direction = Math.sin( direction_in_radians );
double cosine_of_direction = Math.cos( direction_in_radians );
double heading_from_point_2_to_point_1_in_radians = 0.0;
if ( cosine_of_direction != 0.0 )
{
heading_from_point_2_to_point_1_in_radians = atan2( tangent_u, cosine_of_direction ) * 2.0;
}
double cu = 1.0 / Math.sqrt( ( tangent_u * tangent_u ) + 1.0 );
double su = tangent_u * cu;
double sa = cu * sine_of_direction;
double c2a = ( (-sa) * sa ) + 1.0;
double x= Math.sqrt( ( ( ( 1.0 /r /r ) - 1.0 ) * c2a ) + 1.0 ) + 1.0;
x= (x- 2.0 ) / x;
double c= 1.0 - x;
c= ( ( (x * x) / 4.0 ) + 1.0 ) / c;
double d= ( ( 0.375 * (x * x) ) -1.0 ) * x;
tangent_u = distance_in_meters /r / m_EquatorialRadiusInMeters /c;
double y= tangent_u;
boolean exit_loop = false;
double cosine_of_y = 0.0;
double cz = 0.0;
double e = 0.0;
double term_1 = 0.0;
double term_2 = 0.0;
double term_3 = 0.0;
double sine_of_y = 0.0;
while( exit_loop != true )
{
sine_of_y = Math.sin(y);
cosine_of_y = Math.cos(y);
cz = Math.cos( heading_from_point_2_to_point_1_in_radians + y);
e = (cz * cz * 2.0 ) - 1.0;
c = y;
x = e * cosine_of_y;
y = (e + e) - 1.0;
term_1 = ( sine_of_y * sine_of_y * 4.0 ) - 3.0;
term_2 = ( ( term_1 * y * cz * d) / 6.0 ) + x;
term_3 = ( ( term_2 * d) / 4.0 ) -cz;
y= ( term_3 * sine_of_y * d) + tangent_u;
if ( Math.abs(y - c) > eps )
{
exit_loop = false;
}
else
{
exit_loop = true;
}
}
heading_from_point_2_to_point_1_in_radians = ( cu * cosine_of_y * cosine_of_direction ) - ( su * sine_of_y );
c = r * Math.sqrt( ( sa * sa ) + ( heading_from_point_2_to_point_1_in_radians * heading_from_point_2_to_point_1_in_radians ) );
d = ( su * cosine_of_y ) + ( cu * sine_of_y * cosine_of_direction );
double point_2_latitude_in_radians = atan2(d, c);
c = ( cu * cosine_of_y ) - ( su * sine_of_y * cosine_of_direction );
x = atan2( sine_of_y * sine_of_direction, c);
c = ( ( ( ( ( -3.0 * c2a ) + 4.0 ) * m_Flattening ) + 4.0 ) * c2a * m_Flattening ) / 16.0;
d = ( ( ( (e * cosine_of_y * c) + cz ) * sine_of_y * c) + y) * sa;
double point_2_longitude_in_radians = ( point_1_longitude_in_radians + x) - ( ( 1.0 - c) * d * m_Flattening );
heading_from_point_2_to_point_1_in_radians = atan2( sa, heading_from_point_2_to_point_1_in_radians ) + Math.PI;
latitude_in_degrees = Math.toRadians( point_2_latitude_in_radians );
longitude_in_degrees = Math.toRadians( point_2_longitude_in_radians );
}
public double atan2(double y, double x) {
double coeff_1 = Math.PI / 4d;
double coeff_2 = 3d * coeff_1;
double abs_y = Math.abs(y)+ 1e-10f;
double r, angle;
if (x >= 0d) {
r = (x - abs_y) / (x + abs_y);
angle = coeff_1;
} else {
r = (x + abs_y) / (abs_y - x);
angle = coeff_2;
}
angle += (0.1963f * r * r - 0.9817f) * r;
return y < 0.0f ? -angle : angle;
}
private Vector fetchVenues(double max_lat, double min_lat, double max_lon, double min_lon)
{
return new Vector();
}
private class LocationListenerImpl implements LocationListener {
public void locationUpdated(LocationProvider provider, Location location) {
if(location.isValid()) {
nearBy.this.longitude = location.getQualifiedCoordinates().getLongitude();
nearBy.this.latitude = location.getQualifiedCoordinates().getLatitude();
//double altitude = location.getQualifiedCoordinates().getAltitude();
//float speed = location.getSpeed();
}
}
public void providerStateChanged(LocationProvider provider, int newState) {
// MUST implement this. Should probably do something useful with it as well.
}
}
}
package-store\u-finder;
导入java.util.Vector;
导入javax.microedition.location.Criteria;
导入javax.microedition.location.location;
导入javax.microedition.location.LocationException;
导入javax.microedition.location.LocationListener;
导入javax.microedition.location.LocationProvider;
导入javax.microedition.location.QualifiedCoordinates;
导入net.rim.blackberry.api.invoke.invoke;
导入net.rim.blackberry.api.invoke.MapsArguments;
导入net.rim.device.api.system.Bitmap;
导入net.rim.device.api.system.Display;
导入net.rim.device.api.ui.Color;
导入net.rim.device.api.ui.Field;
导入net.rim.device.api.ui.Graphics;
导入net.rim.device.api.ui.Manager;
导入net.rim.device.api.ui.component.BitmapField;
导入net.rim.device.api.ui.component.RichTextField;
导入net.rim.device.api.ui.component.SeparatorField;
导入net.rim.device.api.ui.container.HorizontalFieldManager;
导入net.rim.device.api.ui.container.main屏幕;
导入net.rim.device.api.ui.container.VerticalFieldManager;
公共类扩展了主屏幕{
私人HorizontalFieldManager(顶部);
私人垂直场经理(中),;
私有内水平偏移;
私有最终静态长动画时间=300;
私有长动画开始=0;
私人双纬度=43.7389;
私人双经度=7.42577;
私有整数区间=-1;
私人双最大值;
私人双门;
私人双最大值;
私人双人房;
私人双纬度(单位:度);
私人双经度(单位:度);
附近的公共场所()
{
超级();
horizontalOffset=Display.getWidth();
_top=新的水平字段管理器(Manager.USE_ALL_WIDTH | Field.Field_HCENTER)
{
公共空间涂料(图形gr)
{
位图bg=Bitmap.getBitmapResource(“bg.png”);
gr.drawBitmap(0,0,Display.getWidth(),Display.getHeight(),bg,0,0);
亚漆(gr);
}
};
_中间=新的VerticalFieldManager()
{
公共空间绘制(图形)
{
图形.背景色(0xFFFFFF);
图形.设置颜色(颜色.黑色);
graphics.clear();
超级油漆(图形);
}
受保护的空位子布局(int-maxWidth、int-maxHeight)
{
int displayWidth=Display.getWidth();
int displayHeight=Display.getHeight();
超级子布局(显示宽度、显示高度);
setExtent(显示宽度、显示高度);
}
};
添加(_top);
添加(_中间);
位图lol=Bitmap.getBitmapResource(“logo.png”);
BitmapField lolfield=新的BitmapField(lol);
_添加(lolfield);
标准cr=新标准();
cr.setCostAllowed(true);
cr.setPreferredResponseTime(60);
cr.SET水平精度(5000);
cr.垂直精度(5000);
cr.setAltitudeRequired(真);
cr.IsspeedCourseRequired();
cr.isAddressInfo必需();
试试{
LocationProvider lp=LocationProvider.getInstance(cr);
如果(lp!=null){
lp.setLocationListener(new LocationListenerImpl(),_interval,1,1);
}
}
捕获(位置异常)
{
添加(新的RichTextField(“位置异常”+le));
}
//_添加(新的RichTextField(“这是一张地图”+Double.toString(纬度)+“+Double.toString(经度));
int纬度=(int)(纬度*100000);
int lon=(int)(经度*100000);
字符串文档=“”+”+“+”;
//Invoke.invokeApplication(Invoke.APP_TYPE_映射,新的MapsArguments(MapsArguments.ARG_LOCATION_文档,文档));
_添加(新的分隔符字段());
周边场地();
_添加(新RichTextField(“max-lat:+max_-lat”);
_添加(新的RichTextField(“min lat:+min_lat”);
_添加(新RichTextField(“max-lon:+max_-lon”);
_添加(新RichTextField(“minlon:+minu lon”);
}
场馆周围的私人空间()
{
双点纬度,单位为度=纬度;
双点经度,单位为度=经度;
//对角线距离+误差裕度
双dis