这一篇是我在J2ME Google Maps API的中文翻译,网址在J2ME Google 地图 API!
为了备份,并转贴在此:
这里有一个简单的函式库来查询Google地图,它有下面的功能:
- 地理编码定址到其地理座标
- 撷取给定尺寸、格式及画面远近的静态图片
这个API有一个实例,你可以在这里检查:Java ME Google Maps API sample MIDlet
取得你自己的Google地图API Key
注意:用免费的Google地图API Key的程式使用会违反Google的条款和条件 (10.8节),假如你想要使用Google地图API在上面的范例中,你应该购买企业许可证。
要使用下面的程式码,你应该取得你自己的Google地图API Key,假如你没有API key,你只能照着下面的操作:如何在手机应用程式中使用Google地图资料
使用代理伺服器来存取Google地图服务
注意:这个主题(代理的使用)可能不需要,我们仍然探讨一下..
当你注册取得Google地图API key时,你可以输入位址,这个位址使用那个key能够存取地图服务,因此,你应该设定代理伺服器在那个位址上,这样就能从你的行动用户端收到HTTP请求,转发给Google地图服务,收回Google的回馈反应。
在下面的程式码里你应该发送下面的请求:
- http://www.yourserver.com/geo 请求 http://maps.google.com/maps/geo
- http://www.yourserver.com/staticmap 请 http://maps.google.com/staticmap
原始码:GoogleMaps 类别
import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; import javax.microedition.io.Connector; import javax.microedition.io.HttpConnection; import javax.microedition.lcdui.Image; public class GoogleMaps { private static final String URL_UNRESERVED = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_.~"; private static final char[] HEX = "0123456789ABCDEF".toCharArray(); // these 2 properties will be used with map scrolling methods. You can remove them if not needed public static final int offset = 268435456; public static final double radius = offset / Math.PI; private String apiKey = null; public GoogleMaps(String key) { apiKey = key; } public double[] geocodeAddress(String address) throws Exception { byte[] res = loadHttpFile(getGeocodeUrl(address)); String[] data = split(new String(res, 0, res.length), ','); if (data[0].compareTo("200") != 0) { int errorCode = Integer.parseInt(data[0]); throw new Exception("Google Maps Exception: " + getGeocodeError(errorCode)); } return new double[] { Double.parseDouble(data[2]), Double.parseDouble(data[3]) }; } public Image retrieveStaticImage(int width, int height, double lat, double lng, int zoom, String format) throws IOException { byte[] imageData = loadHttpFile(getMapUrl(width, height, lng, lat, zoom, format)); return Image.createImage(imageData, 0, imageData.length); } private static String getGeocodeError(int errorCode) { switch (errorCode) { case 400: return "Bad request"; case 500: return "Server error"; case 601: return "Missing query"; case 602: return "Unknown address"; case 603: return "Unavailable address"; case 604: return "Unknown directions"; case 610: return "Bad API key"; case 620: return "Too many queries"; default: return "Generic error"; } } private String getGeocodeUrl(String address) { return "http://maps.google.com/maps/geo?q=" + urlEncode(address) + "&output=csv&key=" + apiKey; } private String getMapUrl(int width, int height, double lng, double lat, int zoom, String format) { return "http://maps.google.com/staticmap?center=" + lat + "," + lng + "&format=" + format + "&zoom=" + zoom + "&size=" + width + "x" + height + "&key=" + apiKey; } private static String urlEncode(String str) { StringBuffer buf = new StringBuffer(); byte[] bytes = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(bos); dos.writeUTF(str); bytes = bos.toByteArray(); } catch (IOException e) { // ignore } for (int i = 2; i < bytes.length; i++) { byte b = bytes[i]; if (URL_UNRESERVED.indexOf(b) >= 0) { buf.append((char) b); } else { buf.append('%').append(HEX[(b >> 4) & 0x0f]).append(HEX[b & 0x0f]); } } return buf.toString(); } private static byte[] loadHttpFile(String url) throws IOException { byte[] byteBuffer; HttpConnection hc = (HttpConnection) Connector.open(url); try { hc.setRequestMethod(HttpConnection.GET); InputStream is = hc.openInputStream(); try { int len = (int) hc.getLength(); if (len > 0) { byteBuffer = new byte[len]; int done = 0; while (done < len) { done += is.read(byteBuffer, done, len - done); } } else { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[512]; int count; while ( (count = is.read(buffer)) >= 0 ) { bos.write(buffer, 0, count); } byteBuffer = bos.toByteArray(); } } finally { is.close(); } } finally { hc.close(); } return byteBuffer; } private static String[] split(String s, int chr) { Vector res = new Vector(); int curr; int prev = 0; while ( (curr = s.indexOf(chr, prev)) >= 0 ) { res.addElement(s.substring(prev, curr)); prev = curr + 1; } res.addElement(s.substring(prev)); String[] splitted = new String[res.size()]; res.copyInto(splitted); return splitted; } }
地图卷动的使用方法
假如你需要卷动你的地图,你将需要对你的静态图片计算一个新的中心,下面的adjust()方法传回新的地图中心的经纬度,接受以下的参数:
- 目前中心的经度及纬度座标
- 新地图中心的deltaX及deltaY像素值
- 新地图画面远近程度
原来的程式码是用JavaScript写的,可以在:http://www.polyarc.us/adjust.js下载
注意:要使用下面的方法,你必须将MicroFloat函式库可在这里下载:MicroFloat网站含括到你的专暗李
public double[] adjust(double lat, double lng, int deltaX, int deltaY, int z) { return new double[]{ XToL(LToX(lng) + (deltaX<<(21-z))), YToL(LToY(lat) + (deltaY<<(21-z))) }; } double LToX(double x) { return round(offset + radius * x * Math.PI / 180); } double LToY(double y) { return round( offset - radius * Double.longBitsToDouble(MicroDouble.log( Double.doubleToLongBits( (1 + Math.sin(y * Math.PI / 180)) / (1 - Math.sin(y * Math.PI / 180)) ) )) / 2); } double XToL(double x) { return ((round(x) - offset) / radius) * 180 / Math.PI; } double YToL(double y) { return (Math.PI / 2 - 2 * Double.longBitsToDouble( MicroDouble.atan( MicroDouble.exp(Double.doubleToLongBits((round(y)-offset)/radius)) ) )) * 180 / Math.PI; } double round(double num) { double floor = Math.floor(num); if(num - floor >= 0.5) return Math.ceil(num); else return floor; }
原始码:范例使用
GoogleMaps gMap = new GoogleMaps("API_KEY");
要地理编码一个地址,你可以使用geocodeAddress()方法:
double[] lanLng = gMap.geocodeAddress("Leicester Square, London");
要撷取地图图像:
Image map = gMap.retrieveStaticImage(320, 240, 51.510605, -0.130728, 8, "png32");

我去过这个nokia的网站
那你知道关于定位的写法吗
事实上这部分我很不懂
gps或基地台地位之类的事
但是利用J2ME的location类别
我在SE的手机(z770i)上run不起来
我确定手机有支援JSR-179
所以地图部分现在也只能用预设的经纬度
这样太不方便了
能请教一下你吗
我用NetBeans 6.7在我的Nokia 5800上用http://wiki.forum.nokia.com/index.php/Java_ME_Location_API
这里的范例可以run,但是我的手机卫星讯号很弱,无法定位,但是程式是可以run的,你是怎么使用的,可以再详细告知!