前回はurlからJSONを取得しました、今回は取得した情報を使いやすく加工します。
- JSONをGSONを使いパースする。
- パース結果のworldから大陸、国、州、都市の親子関係を世界情報を生成する。
- 世界情報にパース結果のpackagesを使いパッケージ情報を追加する。
前回作成したサンプルのAsyncTaskLoaderを修正し、上記の処理を追加しました。
public class SkobblerMapInfoDownloadLoader extends AsyncTaskLoader<ArrayList<SkobblerData>> {
public SkobblerMapInfoDownloadLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
forceLoad();
}
@Override
public ArrayList<SkobblerData> loadInBackground() {
SkobblerJson skobblerJson = null;
try {
String jsonUrl = SKPackageManager.getInstance().getMapsJSONPathForCurrentVersion();
HttpURLConnection connection = (HttpURLConnection) new URL(jsonUrl).openConnection();
skobblerJson = SkobblerDataParser.getSkobblerData(connection.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
ArrayList<SkobblerData> skobblerDatas = SkobblerDataParser.parseWorldInfo(skobblerJson.world.get(SkobblerJsonTag.TAG_CONTINENTS));
skobblerDatas = SkobblerDataParser.joinPackageInfo(skobblerDatas, skobblerJson.packages);
return skobblerDatas;
}
/**
* 情報をコンソール出力
* @param inputStream
* @throws IOException
*/
private void showJson(InputStream inputStream) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println(sb.toString());
br.close();
}
}
下記はデータを加工するクラスです。
public class SkobblerDataParser {
/**
* JSONをパースする。
*
* @param inputStream
* @return
*/
public static SkobblerJson getSkobblerData(InputStream inputStream) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
Gson gson = new Gson();
return gson.fromJson(reader, SkobblerJson.class);
}
/**
* パース結果のworldから大陸、国、州、都市の親子関係を世界情報を生成する。
* @param continents
* @return
*/
public static ArrayList<SkobblerData> parseWorldInfo(ArrayList<HashMap<String, Object>> continents) {
ArrayList<SkobblerData> skobblerDatas = new ArrayList<>();
for (HashMap<String, Object> continent : continents) {
String continentCode;
//大陸の情報
if (continent.containsKey(SkobblerJsonTag.TAG_CONTINENT_CODE)) {
continentCode = (String) continent.get(SkobblerJsonTag.TAG_CONTINENT_CODE);
SkobblerData skobblerData = new SkobblerData(SkobblerData.SUBTYPE_CONTINENT, continentCode, null);
skobblerDatas.add(skobblerData);
} else {
break;
}
if (continent.containsKey(SkobblerJsonTag.TAG_COUNTRIES)) {
//国の情報
ArrayList<Map<String, Object>> countries = (ArrayList<Map<String, Object>>) continent.get(SkobblerJsonTag.TAG_COUNTRIES);
for (Map<String, Object> country : countries) {
String countryCode = (String) country.get(SkobblerJsonTag.TAG_COUNTRY_CODE);
SkobblerData skobblerData = new SkobblerData(SkobblerData.SUBTYPE_COUNTRY, countryCode, continentCode);
skobblerDatas.add(skobblerData);
if (country.containsKey(SkobblerJsonTag.TAG_CITY_CODES)) {
//都市の情報
ArrayList<Map<String, Object>> cities = (ArrayList<Map<String, Object>>) country.get(SkobblerJsonTag.TAG_CITY_CODES);
for (Map<String, Object> city : cities) {
skobblerData = new SkobblerData(SkobblerData.SUBTYPE_CITY, (String) city.get(SkobblerJsonTag.TAG_CITY_CODE), countryCode);
skobblerDatas.add(skobblerData);
}
} else if (country.containsKey(SkobblerJsonTag.TAG_STATE_CODES_ID)) {
//州の情報
ArrayList<Map<String, Object>> states = (ArrayList<Map<String, Object>>) country.get(SkobblerJsonTag.TAG_STATE_CODES_ID);
for (Map<String, Object> state : states) {
String stateCode = (String) state.get(SkobblerJsonTag.TAG_STATE_CODE_ID);
skobblerData = new SkobblerData(SkobblerData.SUBTYPE_STATE, stateCode, countryCode);
skobblerDatas.add(skobblerData);
ArrayList<Map<String, Object>> cities = (ArrayList<Map<String, Object>>) state.get(SkobblerJsonTag.TAG_CITY_CODES);
if (cities != null) {
for (Map<String, Object> city : cities) {
skobblerData = new SkobblerData(SkobblerData.SUBTYPE_CITY, (String) city.get(SkobblerJsonTag.TAG_CITY_CODE), stateCode);
skobblerDatas.add(skobblerData);
}
}
}
}
}
}
}
return skobblerDatas;
}
/**
* 世界情報にパース結果のpackagesを使いパッケージ情報を追加する。
* @param continents
* @return
*/
public static ArrayList<SkobblerData> joinPackageInfo(ArrayList<SkobblerData> skobblerDatas, ArrayList<HashMap<String, Object>> packages) {
for (HashMap<String, Object> packageInfo : packages) {
String packageCode = (String) packageInfo.get(SkobblerJsonTag.TAG_PACKAGE_CODE);
for (SkobblerData skobblerData : skobblerDatas) {
if (packageCode.equals(skobblerData.getCode())) {
//全サイズ
skobblerData.setSize((Double) packageInfo.get(SkobblerJsonTag.TAG_SIZE));
//解凍サイズ
skobblerData.setUnzipSize((Double) packageInfo.get(SkobblerJsonTag.TAG_UNZIP_SIZE));
//ファイル名
skobblerData.setFile((String) packageInfo.get(SkobblerJsonTag.TAG_FILE));
//SKMファイルのサイズ
skobblerData.setSkmSize((Double) packageInfo.get(SkobblerJsonTag.TAG_SKM_SIZE));
//NBZIPのファイル名
skobblerData.setNbZip((String) packageInfo.get(SkobblerJsonTag.TAG_NB_ZIP));
//タイプ
skobblerData.setType((Double) packageInfo.get(SkobblerJsonTag.TAG_TYPE));
//最大最小緯度経度
Map<String, Object> bbox = (Map<String, Object>) packageInfo.get(SkobblerJsonTag.TAG_BBOX);
if (bbox != null) {
//最小緯度
skobblerData.setLatitudeMin((Double) bbox.get(SkobblerJsonTag.TAG_LAT_MIN));
//最大緯度
skobblerData.setLatitudeMax((Double) bbox.get(SkobblerJsonTag.TAG_LAT_MAX));
//最小経度
skobblerData.setLongtudeMin((Double) bbox.get(SkobblerJsonTag.TAG_LONG_MIN));
//最大経度
skobblerData.setLongtudeMax((Double) bbox.get(SkobblerJsonTag.TAG_LONG_MAX));
}
//テクスチャの情報を作成
Map<String, Object> texture = (Map<String, Object>) packageInfo.get(SkobblerJsonTag.TAG_TEXTURE);
if (texture != null) {
skobblerData.setTexturesBigFile((String) texture.get(SkobblerJsonTag.TAG_TEXTURES_BIG_FILE));
skobblerData.setTextureUnzipSize((Double) texture.get(SkobblerJsonTag.TAG_UNZIP_SIZE));
skobblerData.setTextureSize((Double) texture.get(SkobblerJsonTag.TAG_SIZE));
skobblerData.setTextureFile((String) texture.get(SkobblerJsonTag.TAG_FILE));
skobblerData.setTextureSizeBigFile((Double) texture.get(SkobblerJsonTag.TAG_SIZE_BIG_FILE));
}
//言語ごとの呼び方一覧
ArrayList<Map<String, String>> languages = (ArrayList<Map<String, String>>) packageInfo.get(SkobblerJsonTag.TAG_LANGUAGES);
for (Map<String, String> language : languages) {
if ("en".equals(language.get("lngCode"))) {
skobblerData.setName(language.get("tlName"));
break;
}
}
skobblerData.setLanguages(languages);
//標高?
Map<String, Object> elevation = (Map<String, Object>) packageInfo.get(SkobblerJsonTag.TAG_ELEVATION);
if (elevation != null) {
skobblerData.setElevationFile((String) elevation.get(SkobblerJsonTag.TAG_FILE));
skobblerData.setElevationSize((Double) elevation.get(SkobblerJsonTag.TAG_SIZE));
skobblerData.setElevationUnzipSize((Double) elevation.get(SkobblerJsonTag.TAG_UNZIP_SIZE));
}
break;
}
}
}
return skobblerDatas;
}
}
下記はGSONを使いJSON文字列から変換するクラスです。
public class SkobblerJson {
/**世界構成の情報*/
public HashMap<String, ArrayList<HashMap<String, Object>>> world;
/**パッケージ情報*/
public ArrayList<HashMap<String, Object>> packages;
}
下記はすべての加工が終わった時にデータを保持するデータクラスです。
正直、使い道がわからない情報があります。
public class SkobblerData {
public static final String SUBTYPE_CONTINENT = "continent";
public static final String SUBTYPE_COUNTRY = "country";
public static final String SUBTYPE_CITY = "city";
public static final String SUBTYPE_STATE = "state";
/**
* タイプ(大陸、国、州、都市)
*/
private String subType;
/**
* Skobbler内の一意なコード
*/
private String code;
/**
* 英語名
*/
private String name;
/**
* 親のSkobblerコード
*/
private String parentCode;
/**
* 圧縮時の容量
*/
private double size;
/**
* 解凍時の容量
*/
private double unzipSize;
/**
* zipファイル名
*/
private String file;
/**
* SKMファイル容量
*/
private double skmSize;
/**
* 最小緯度
*/
private double latitudeMin;
/**
* 最大緯度
*/
private double latitudeMax;
/**
* 最小経度
*/
private double longtudeMin;
/**
* 最大経度
*/
private double longtudeMax;
/**
* 言語ごとの呼び方
*/
private ArrayList<Map<String, String>> languages;
/**
* わからない
*/
private String nbZip;
private double type;
private String texturesBigFile;
private double textureUnzipSize;
private double textureSize;
private String textureFile;
private double textureSizeBigFile;
private double elevationUnzipSize;
private double elevationSize;
private String elevationFile;
public SkobblerData(String subType, String code, String parentCode) {
this.subType = subType;
this.code = code;
this.parentCode = parentCode;
}
public String getSubType() {
return subType;
}
public void setSubType(String subType) {
this.subType = subType;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getParentCode() {
return parentCode;
}
public void setParentCode(String parentCode) {
this.parentCode = parentCode;
}
public double getSize() {
return size;
}
public void setSize(double size) {
this.size = size;
}
public String getTexturesBigFile() {
return texturesBigFile;
}
public void setTexturesBigFile(String texturesBigFile) {
this.texturesBigFile = texturesBigFile;
}
public double getTextureUnzipSize() {
return textureUnzipSize;
}
public void setTextureUnzipSize(double textureUnzipSize) {
this.textureUnzipSize = textureUnzipSize;
}
public double getTextureSize() {
return textureSize;
}
public void setTextureSize(double textureSize) {
this.textureSize = textureSize;
}
public String getTextureFile() {
return textureFile;
}
public void setTextureFile(String textureFile) {
this.textureFile = textureFile;
}
public double getTextureSizeBigFile() {
return textureSizeBigFile;
}
public void setTextureSizeBigFile(double textureSizeBigFile) {
this.textureSizeBigFile = textureSizeBigFile;
}
public ArrayList<Map<String, String>> getLanguages() {
return languages;
}
public void setLanguages(ArrayList<Map<String, String>> languages) {
this.languages = languages;
}
public double getUnzipSize() {
return unzipSize;
}
public void setUnzipSize(double unzipSize) {
this.unzipSize = unzipSize;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
public String getElevationFile() {
return elevationFile;
}
public void setElevationFile(String elevationFile) {
this.elevationFile = elevationFile;
}
public double getElevationSize() {
return elevationSize;
}
public void setElevationSize(double elevationSize) {
this.elevationSize = elevationSize;
}
public double getElevationUnzipSize() {
return elevationUnzipSize;
}
public void setElevationUnzipSize(double elevationUnzipSize) {
this.elevationUnzipSize = elevationUnzipSize;
}
public double getSkmSize() {
return skmSize;
}
public void setSkmSize(double skmSize) {
this.skmSize = skmSize;
}
public String getNbZip() {
return nbZip;
}
public void setNbZip(String nbZip) {
this.nbZip = nbZip;
}
public double getType() {
return type;
}
public void setType(double type) {
this.type = type;
}
public double getLatitudeMin() {
return latitudeMin;
}
public void setLatitudeMin(double latitudeMin) {
this.latitudeMin = latitudeMin;
}
public double getLatitudeMax() {
return latitudeMax;
}
public void setLatitudeMax(double latitudeMax) {
this.latitudeMax = latitudeMax;
}
public double getLongtudeMin() {
return longtudeMin;
}
public void setLongtudeMin(double longtudeMin) {
this.longtudeMin = longtudeMin;
}
public double getLongtudeMax() {
return longtudeMax;
}
public void setLongtudeMax(double longtudeMax) {
this.longtudeMax = longtudeMax;
}
}
パースのために使うタグです。
public class SkobblerJsonTag {
public static final String TAG_CONTINENTS = "continents";
public static final String TAG_COUNTRIES = "countries";
public static final String TAG_CITY_CODES = "cityCodes";
public static final String TAG_CONTINENT_CODE = "continentCode";
public static final String TAG_COUNTRY_CODE = "countryCode";
public static final String TAG_CITY_CODE = "cityCode";
public static final String TAG_STATE_CODES_ID = "stateCodes";
public static final String TAG_STATE_CODE_ID = "stateCode";
public static final String TAG_PACKAGE_CODE = "packageCode";
public static final String TAG_SIZE = "size";
public static final String TAG_TEXTURE = "texture";
public static final String TAG_TEXTURES_BIG_FILE = "texturesbigfile";
public static final String TAG_UNZIP_SIZE = "unzipsize";
public static final String TAG_FILE = "file";
public static final String TAG_SIZE_BIG_FILE = "sizebigfile";
public static final String TAG_LANGUAGES = "languages";
public static final String TAG_ELEVATION = "elevation";
public static final String TAG_SKM_SIZE = "skmsize";
public static final String TAG_NB_ZIP = "nbzip";
public static final String TAG_TYPE = "type";
public static final String TAG_BBOX = "bbox";
public static final String TAG_LAT_MIN = "latMin";
public static final String TAG_LAT_MAX = "latMax";
public static final String TAG_LONG_MIN = "longMin";
public static final String TAG_LONG_MAX = "longMax";
}