×
Namespaces

Variants
Actions

Archived:Google Maps API in Java ME(日本語)

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Since this article was written, alternative Map Tile caching solutions for Java ME have become available. Map Tile caching solutions such as the Nokia Maps API for Java ME have several advantages over static mapping solutions such as the static Google Maps API including:

  • Static mapping services such as the Google Static Maps API or Nokia's RESTful Map API do not cache or tile the images when requested, therefore each request involves a round trip to the server. If the map on a mobile application needs to be refreshed at any time, using a caching library will result in a reduction in network traffic after around three maps have been displayed. An explanation of this can be found here
  • As the name implies, Google's Static Maps API can only retrieve over http static images for a requested coordinate point, image size, image type and zoom level. Newer libraries offer additional functionality out of the box offering dynamic Map content and touch support, where the user can move around his/her current position, zoom in, zoom out, modify the view mode to satellite or translate an address to a coordinate point and show that on the map, among others. This abstraction of the underlying functionality is hidden from the developer,os much less coding is needed in order to achieve the same result .

Additionally the following points apply in favour of Nokia Maps when comparing to Google Maps:

  • No legal restrictions of using the API outside a web browser application or need to provide a link to the native Google Maps App (if there is one), or to Google Maps (if there isn't one). See Terms of Service below.
  • Higher free daily request limits. Nokia Maps API for Java ME supports up to 50,000 render requests per day and per unique IP address (as of January 2012), for Nokia Developer registered users (free of charge) while the limit for Google's Static Maps API is currently 1000 unique (different) image requests per viewer per day.
An article with the same functionality, written with Nokia Maps API for Java ME, that uses much less code can be found here

本記事で説明するのは、以下の機能についてGoogle Mapsに問い合わせる、簡単なライブラリです。

  • 地理的座標へのジオコードアドレス
  • カスタム指定したサイズ・フォーマット・ズームで静止画像を取得する

本APIを使ったサンプル例を見たい場合、下記サイトで確認できます。 Java ME Google Maps API sample MIDlet

Contents

ユーザー専用の Google Maps API キーを取得する

以下に示すコードを使用するため、Google Maps APIキーを取得する必要があります。APIキーをまだ取得していない場合、次の手順に従って取得できます。Archived:How to use Google Static Maps data in mobile applications

Google Map サービスにアクセスするため、Proxyサーバを使用する

注意事項: 本題(Proxyの使用)は不要かもしれません。現在もまだ調査中です。
Google Maps APIキーを取得するためにサインアップ(sign up)する際、そのキーでMapsサービスにアクセス可能なアドレスを入力します。このため、そのアドレス上に、端末クライアントからのHTTPリクエストを受取り、それをGoogle Mapsサービスへ転送し、Googleからのレスポンスをクライアントに返すProxyサーバを設定する必要があります。

下記コード中で、次のリクエストを転送します。

  • http://www.yourserver.com/error.html から http://maps.google.com/maps/geo へのリクエスト
  • http://www.yourserver.com/error.html からhttp://maps.google.com/staticmap へのリクエスト

ソースコード: GoogleMaps クラス

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
 
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Image;
 
public class GoogleMaps
{
String apiKey = null;
 
//these 2 properties will be used with map scrolling methods. You can remove them if not needed
int offset = 268435456;
double radius = offset / Math.PI;
 
public GoogleMaps(String apiKey)
{
this.apiKey = apiKey;
}
 
public double[] geocodeAddress(String address) throws Exception
{
byte[] res = loadHttpFile(getGeocodeUrl(address));
 
String resString = new String(res, 0, res.length);
 
String[] data = split(resString, ',');
 
if(data[0].compareTo("200") != 0)
{
int errorCode = Integer.parseInt(data[0]);
 
throw new Exception("Google Maps Exception: " + getGeocodeError(errorCode));
}
else
{
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 Exception
{
byte[] imageData = loadHttpFile(getMapUrl(width, height, lng, lat, zoom, format));
 
return Image.createImage(imageData, 0, imageData.length);
}
 
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";
}
}
 
String getGeocodeUrl(String address)
{
return "http://maps.google.com/maps/geo?q=" + urlEncode(address)
+ "&output=csv&key=" + apiKey;
}
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;
}
String urlEncode(String str)
{
StringBuffer buf = new StringBuffer();
char c;
for(int i = 0; i < str.length(); i++)
{
c = str.charAt(i);
if ((c >= '0' && c <= '9')||
(c >= 'A' && c <= 'Z')||
(c >= 'a' && c <= 'z'))
{
buf.append(c);
}
else
{
buf.append("%").append(Integer.toHexString((int) str.charAt(i)));
}
}
return buf.toString();
}
byte[] loadHttpFile(String url) throws Exception
{
HttpConnection hc = null;
 
InputStream is = null;
 
byte[] byteBuffer = null;
 
try
{
hc = (HttpConnection) Connector.open(url);
 
hc.setRequestMethod(HttpConnection.GET);
 
int ch;
 
is = hc.openInputStream();
 
int len = (int)hc.getLength();
 
if(len > 0)
{
byteBuffer = new byte[len];
 
is.read(byteBuffer);
}
else
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
while ((ch = is.read()) != -1)
{
bos.write(ch);
}
byteBuffer = bos.toByteArray();
 
bos.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if(is != null)
is.close();
 
if(hc != null)
hc.close();
}
catch(Exception e2)
{
e2.printStackTrace();
}
}
return byteBuffer;
}
static String[] split(String s, int chr)
{
Vector res = new Vector();
 
int curr = 0;
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() メソッドは、以下の引数を受取り、新しい緯度経度の中心値を返します。

  • 現在の 緯度(latitute)経度(longitude) の中心座標
  • 新しいマップ中心位置の X差分(deltaX)Y差分(deltaY) (ピクセル値)
  • マップの ズーム(zoom) レベル


オリジナルのJavaScriptコードは、こちらから取得できます。 http://home.provide.net/~bratliff/adjust.js

注意事項: 次のメソッドを使用する場合、作成アプリケーションのプロジェクト中に MicroFloat ライブラリをインクルードする必要があります。ライブラリはこちらから取得できます。MicroFloat Webサイト

public double[] adjust(double lat, double lng, int deltaX, int deltaY, int z)
{
return new double[]{
XToL(LToX(lat) + (deltaX<<(21-z))),
YToL(LToY(lng) + (deltaY<<(21-z)))
};
}
double LToX(double x)
{
return round(offset + radius * Math.toRadians(x));
}
 
double LToY(double y)
{
return round(
offset - radius *
Double.longBitsToDouble(MicroDouble.log(
Double.doubleToLongBits(
(1 + Math.sin(Math.toRadians(y)))
/
(1 - Math.sin(Math.toRadians(y)))
)
)) / 2);
}
 
double XToL(double x)
{
return Math.toDegrees((round(x) - offset) / radius);
}
 
double YToL(double y)
{
return Math.toDegrees(Math.PI / 2 - 2 * Double.longBitsToDouble(
MicroDouble.atan(
MicroDouble.exp(Double.doubleToLongBits((round(y)-offset)/radius))
)
));
}
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("Leicester Square, London");

マップ画像を取得します。

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

 

This page was last modified on 16 August 2013, at 07:08.
108 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×