Namespaces
Variants
Actions

J2ME Google 地圖 API

Jump to: navigation, search
WP Metro Icon Chinese.png
文章信息

文章
User:Linux achi 在 15 Jul 2009 创建
最后由 hamishwillee 在 15 Dec 2011 编辑

這裡有一個簡單的函式庫來查詢Google地圖,它有下面的功能:

  • 地理編碼定址到其地理座標
  • 擷取給定尺寸、格式及畫面遠近的靜態圖片

這個API有一個實例,你可以在這裡檢查:Java ME Google Maps API sample MIDlet

Contents

取得你自己的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/error.html 請求 http://maps.google.com/maps/geo
  • http://www.yourserver.com/error.htmlhttp://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/maps/api/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()方法傳回新的地圖中心的經緯度,接受以下的參數:

  • 目前中心的經度緯度座標
  • 新地圖中心的deltaXdeltaY像素值
  • 新地圖畫面遠近程度


原來的程式碼是用JavaScript寫的,可以在:http://home.provide.net/~bratliff/adjust.js下載

注意:如果你使用的是CLDP 1.0的話,要使用下面的方法,你必須將MicroFloat函式庫可在這裡下載:MicroFloat網站含括到你的專案裡,現在在CLDP 1.1已經支援float及double了!

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;
}

原始碼:範例使用

J2me google maps.jpg
要使用這個類別,首先先用你的API金鑰:

GoogleMaps gMap = new GoogleMaps("API_KEY");

要地理編碼一個地址,你可以使用geocodeAddress()方法:

double[] lanLng = gMap.geocodeAddress("中壢市永泰街129號");

要擷取地圖圖像:

Image map = gMap.retrieveStaticImage(320, 240, 51.510605, -0.130728, 8, "png32");


相关链接

This page was last modified on 15 December 2011, at 08:11.
115 page views in the last 30 days.
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2013 All rights reserved