編輯:關於Android編程
GML,地理標記語言(外語全稱:Geography MarkupLanguage、外語縮寫:GML),它由開放式地理信息系統協會(外語縮寫:OGC)於1999年提出,並得到了許多公司的大力支持,如Oracle、Galdos、MapInfo、CubeWerx等。GML能夠表示地理空間對象的空間數據和非空間屬性數據
GML文檔的本質還是Xml文檔,所以可以用Xml解析器進行解析,在Android中可以使用自帶的XmlPullParser進行解析,當然你也可以用SAX解析器可DOM解析器。在GML文檔中有兩種屬性,一類是空間屬性,另外一個就是非空間屬性。其中空間屬性是至關重要的,因為要進行地圖顯示必須要用空間屬性;而非空間屬性可以不用,但是由於要進行查詢操作,所以我將非空間屬性也進行存儲。
在讀GML文檔時,首先讀取圖層,然後判斷圖層中的屬性都有哪些,如果是非空間屬性,將其存儲起來(我用的是Sqlite數據庫),如果是空間屬性,那麼第一個空間屬性肯定是關於圖層類型的,即他是Polygen,Polyline或是Point,然後在或標簽下存儲的位置信息,將位置信息存儲起來即可。
以上就是大致的讀取GML文檔的思路。
地圖顯示的方法有很多種,我簡單介紹兩種,一種是使用畫布canvas進行繪制,另外一種就是使用SVG進行顯示。由於我的水平有限,想不出解決canvas加載重繪時卡頓的問題,所以我就使用svg進行顯示,使用svg最大的好處就是只在首次使用的時候生成SVG文件而花費的時間較長,而在之後的使用中加載時間在1s以內;另外就是使用svg進行功能實現時不會出現卡頓或者說是卡頓比前一種方法小的多。(在文件夾中包含的使用canvas繪制的工程是我找我的學長要的,哈哈)。
關於SVG大家有不明白的直接去百度,那裡面比我講的清楚的多,在寫SVG的時候注意下面幾個事項就行:
由於GML文件裡面位置數據過大,所以需要在SVG中設置ViewBox保證地圖能夠全部顯示(關於ViewBox也去百度吧)。
坐標轉換,在GML中默認的坐標原點是左下角,而SVG的坐標原點是左上角,這點我想大家都因應該在之前接觸過,所以需要進行坐標轉換,就是進行垂直翻轉而已。最初我使用的方法是將每個坐標的縱坐標變成相反數,然後就導致寫SVG文件花了2分鐘……。這樣當然不行啊,找別的方法吧,後來終於找到個好辦法,用矩陣變換,就是SVG裡面的matrix屬性,一下就變成10s以內,真是……
圖層順序,寫SVG的時候圖層顯示應該按照面線點文字的順序,這樣可以保證所有圖層都能夠顯示
因為我用的SVG,所以沒必要再進行SVG解析,直接用浏覽器就可以查看,所以我只需要實現一個浏覽器的功能就行了,用WebView控件,由於SVG的放大縮小平移可以用Javascript實現,所以我的所有功能都是在Javascript中的。但是在Android裡面直接加載SVG文件會導致Javascript失效,所以用html內聯SVG,這個也不再多說,大家參考html文件即可。
放大縮小:放大縮小的功能就是變化ViewBox即可,大家可以參考文件夾裡面的js文件。
平移:平移功能要重寫WebView的ontouch事件,然後再調用Javascript函數,具體也不多說,大家自己看吧。
搜索:搜索分為兩部分,首先是從數據庫中按照搜索條件查詢出對象的ID,然後調用Javascript搜索的相關函數搜索出SVG中對應的對象。
第一次進入應用時,先解析GML,將數據存儲在數據庫中,生成SVG,用webView顯示HTML來顯示SVG,在裡面用JS實現一些功能控制,第二次進入時直接加載SVG即可
package com.gmlmap.activity;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import com.gmlmap.data.LayerInfo;
import com.gmlmap.readfile.GmlPullParser;
import com.gmlmap.readfile.SvgWrite;
import com.gmlmap.util.SetViewHeight;
import com.gmlmap.util.SharedUtils;
import com.gmlmap.view.DrawerGarment;
import com.gmlmap.view.DrawerGarment.IDrawerCallbacks;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.Window;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class Activity_Main extends Activity {
private ProgressDialog dialog;
private WebView m_webview;
private Button m_btzoomin;
private Button m_btzoomout;
private Button m_btser;
private EditText m_edit;
private GestureDetector mGestureDetector;
//抽屜使用
private DrawerGarment mDrawerGarment;
private TextView mButton;
private TextView m_text;
private ListView m_listview;
private MAdapter m_adapter;
private ArrayList m_layers;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.title); //titlebar為自己標題欄的布局
getSvg();
}
private void InitCtView()
{
mDrawerGarment = new DrawerGarment(this, R.layout.drawer);
m_layers=SharedUtils.getLayers(getApplicationContext(), "TestData");
m_text=(TextView)this.findViewById(R.id.textView1);
m_text.setText("圖層");
m_listview=(ListView)this.findViewById(R.id.listview);
m_adapter=new MAdapter(this,m_layers);
m_listview.setAdapter(m_adapter);
SetViewHeight.setLvHeight(m_listview);
mDrawerGarment.setDrawerCallbacks(new IDrawerCallbacks() {
@Override
public void onDrawerOpened() {
}
@Override
public void onDrawerClosed() {
}
});
mButton = (TextView) findViewById(R.id.bt_chou);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mDrawerGarment.toggleDrawer();
}
});
}
String move="";
@SuppressLint("SetJavaScriptEnabled")
private void initwebview() {
m_webview = (WebView) findViewById(R.id.webview);
WebSettings webSettings = m_webview.getSettings();
webSettings.setLoadWithOverviewMode(true);
webSettings.setJavaScriptEnabled(true);
m_webview.setWebViewClient(new WebViewClient());
m_webview.setWebChromeClient(new WebChromeClient());
// SVG圖所在路徑
String svg_path="file:///mnt/sdcard/GmlParser/TestData/index.html";
m_webview.loadUrl(svg_path);
mGestureDetector = new GestureDetector(this, new MyOnGestureListener());
m_webview.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
mGestureDetector.onTouchEvent(event);
return true;
}});
m_edit=(EditText)this.findViewById(R.id.edittext);
m_btzoomin=(Button)this.findViewById(R.id.mapzoomin);
m_btzoomout=(Button)this.findViewById(R.id.mapzoomout);
m_btser=(Button)this.findViewById(R.id.bt_search);
m_btser.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String co=m_edit.getText().toString();
if(co.equals(""))
Toast.makeText(getApplicationContext(), "輸入不能為空",Toast.LENGTH_SHORT).show();
else
{
String id=SharedUtils.getOid(getApplicationContext(), "TestData", co);
if(id.equals(""))
Toast.makeText(getApplicationContext(), "沒有搜索到結果",Toast.LENGTH_SHORT).show();
else
m_webview.loadUrl("javascript:searchByid('"+id+"')");
m_edit.setText("");
}
}});
m_btzoomin.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
m_webview.loadUrl("javascript:ZoomIn()");
}});
m_btzoomout.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
m_webview.loadUrl("javascript:ZoomOut()");
}});
}
private boolean GmlRead() {
boolean result = false;
try {
InputStream is = getAssets().open("TestData.gml");
result = GmlPullParser.parse(is, "TestData", this);
} catch (IOException e) {
// TODO Auto-generated catch block
result = false;
}
return result;
}
// Handler
@SuppressLint("HandlerLeak")
Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
initwebview();
InitCtView();
break;
case 1:
Toast.makeText(getApplicationContext(), "Gml解析發生錯誤", Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(getApplicationContext(), "Svg生成發生錯誤", Toast.LENGTH_SHORT).show();
break;
}
dialog.dismiss();
}
};
class mainThread implements Runnable {
@Override
public void run() {
Message msg = handler.obtainMessage();
if (GmlRead()) {
SvgWrite m_writer = new SvgWrite(Activity_Main.this);
if (m_writer.Write())
msg.what = 0;// SVG生成成功
else
msg.what = 2;// svg生成失敗
} else
msg.what = 1;// gml解析失敗
handler.sendMessage(msg);
}
}
private void getSvg() {
if (SharedUtils.getBooleanValue(Activity_Main.this, "isStored", false)
&& SharedUtils.getBooleanValue(Activity_Main.this, "isSvg",
false))
{
initwebview();
InitCtView();
}else {
Toast.makeText(getApplicationContext(), "首次進入系統會花費5~20秒的時間進行數據解析,請勿退出~!",Toast.LENGTH_LONG).show();
/**
* 進度條
*/
dialog = new ProgressDialog(Activity_Main.this,
ProgressDialog.THEME_HOLO_LIGHT);
dialog.setMessage("正在解析GML並生成SVG,請稍後……");
dialog.setCanceledOnTouchOutside(false);
dialog.show();
Thread mainThread = new Thread(new mainThread());
// CheckNetworkState();
mainThread.start();
}
}
public class MAdapter extends BaseAdapter {
private ArrayList layers;
private ArrayList status;
private LayoutInflater m_listContainer; // 視圖容器
private Context context;
class Views{
CheckBox m_check;
LinearLayout button;
}
public MAdapter(Context context,ArrayList mlayers)
{
this.context=context;
layers=mlayers;
status=new ArrayList();
m_listContainer = LayoutInflater.from(context); // 創建視圖容器並設置上下文
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return layers.size();
}
@Override
public Object getItem(int arg0) {
// TODO Auto-generated method stub
return layers.get(arg0);
}
@Override
public long getItemId(int arg0) {
// TODO Auto-generated method stub
return arg0;
}
@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
Views m_views;
if (arg1 == null) {
arg1 = m_listContainer.inflate(R.layout.listdetail,
null);
m_views=new Views();
m_views.m_check = (CheckBox) arg1.findViewById(R.id.checkbox);
//m_views.button=(LinearLayout)arg1.findViewById(R.id.bt_attr);
m_views.m_check.setText(layers.get(arg0).Lname);
m_views.m_check.setTag(arg0);
//m_views.button.setTag(layers.get(arg0).Lid);
status.add(false);
arg1.setTag(m_views);
} else {
m_views = (Views) arg1.getTag();
}
m_views.m_check.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
m_webview.loadUrl("javascript:changeVisible('L_"+v.getTag()+"')");
}
});
/*m_views.button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent(Activity_Main.this,Activity_attr.class);
intent.putExtra("name", "L_"+v.getTag());
startActivity(intent);
}});*/
return arg1;
}
}
class MyOnGestureListener extends SimpleOnGestureListener{
//滑動 Drag
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
m_webview.loadUrl("javascript:scrool("+distanceX+","+distanceY+")");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
m_webview.loadUrl("javascript:ZoomIn()");
return false;
}
//抬起
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
}
}
package com.gmlmap.readfile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import com.gmlmap.data.LayerInfo;
import com.gmlmap.data.PosInfo;
import com.gmlmap.util.SharedUtils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Xml;
public class GmlPullParser {
public static String GML_PREFIX="http://www.opengis.net/gml" ;
public final static int CASE_NORMAL=0; //一般情況,不進行任何操作,直接跳
public final static int CASE_FIRSTREAD=1; //第一次讀featureMember,即讀取圖層的第一個要素
public final static int CASE_READ=2; //讀取圖層的第二個以後的要素
public final static int CASE_READLNAME=3; //讀取圖層名稱
public static String SQL_NORMAL_INSERT="insert into";
public static String SQL_NORMAL_CREATE="CREATE TABLE";
public static boolean parse(InputStream is,String filename,Context context){
boolean result=false;
SharedUtils.StorePreferences(context, "filename", filename);
ArrayList AttrNames=new ArrayList();
LayerInfo m_layerinfo=new LayerInfo();
PosInfo m_posinfo=new PosInfo();
int m_curCondition=CASE_NORMAL;//當前位置
//打開或創建數據庫
SQLiteDatabase db = context.openOrCreateDatabase(filename+".db", Context.MODE_PRIVATE, null);
db.beginTransaction();
db.execSQL("DROP TABLE IF EXISTS LayersInfo");
db.execSQL("create table LayersInfo (Lid INTEGER primary key,Lname VARCHAR(20),Ltype INTEGER)");
db.execSQL("DROP TABLE IF EXISTS FeaturePositon");
db.execSQL("create table FeaturePositon (Pid INTEGER primary key,Lid INTEGER,OBJECTID INTEGER,Pos TEXT)");
//創建xml pull解析器
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(is, "UTF-8");
int eventType = parser.getEventType();
while (eventType!=XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
if (parser.getName().equals("featureMember")) {
m_curCondition=CASE_READLNAME;
}
else if(parser.getName().equals("lowerCorner"))
{
eventType=parser.next();
SharedUtils.StorePreferences(context,"lowerCorner",parser.getText());
}
else if(parser.getName().equals("upperCorner"))
{
eventType=parser.next();
SharedUtils.StorePreferences(context,"upperCorner",parser.getText());
}
else if(m_curCondition!=CASE_NORMAL && parser.getNamespace().equals(GML_PREFIX))
{
m_layerinfo.Ltype=getLayerType(parser.getName());
eventType = parser.next();
while (eventType!=XmlPullParser.END_DOCUMENT)
{
if(parser.getName()!=null && parser.getName().contains("pos"))
{
eventType = parser.next();
m_posinfo.Pos=parser.getText();
db.execSQL(m_posinfo.insertData());
m_posinfo.Pid++;
break;
}
else
eventType = parser.next();
}
}
else
{
switch(m_curCondition)
{
case CASE_READLNAME:
if(!parser.getName().equals(m_layerinfo.Lname))
{
m_layerinfo.Lid++;
m_layerinfo.Ltype=-1;
m_posinfo.Lid=m_layerinfo.Lid;
m_layerinfo.Lname=parser.getName();
m_curCondition=CASE_FIRSTREAD;
AttrNames.removeAll(AttrNames);
}
else
m_curCondition=CASE_READ;
m_layerinfo.InitInfo();
break;
case CASE_FIRSTREAD:
boolean ifObj=false;
m_layerinfo.AddInsertName(parser.getName());
AttrNames.add(parser.getName());
if(parser.getName().equals("OBJECTID"))
ifObj=true;
else
m_layerinfo.AddCreate(parser.getName());
eventType = parser.next();
m_layerinfo.AddInsertValue(parser.getText());
if(ifObj)
m_posinfo.OBJECTID=Integer.parseInt(parser.getText());
break;
case CASE_READ:
if(AttrNames.contains(parser.getName()))
{
boolean ifObj2=false;
if(parser.getName().equals("OBJECTID"))
ifObj2=true;
m_layerinfo.AddInsertName(parser.getName());
eventType = parser.next();
m_layerinfo.AddInsertValue(parser.getText());
if(ifObj2)
m_posinfo.OBJECTID=Integer.parseInt(parser.getText());
}
break;
}
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("featureMember")) {
if(m_curCondition==CASE_FIRSTREAD)
{
db.execSQL("DROP TABLE IF EXISTS L_"+m_layerinfo.Lid);
db.execSQL(m_layerinfo.getCreateInfo());
db.execSQL(m_layerinfo.insertData());
}
db.execSQL(m_layerinfo.getInsertInfo());
}
break;
case XmlPullParser.END_DOCUMENT:
break;
}
eventType = parser.next();
}
//關閉當前數據庫
db.setTransactionSuccessful();
db.endTransaction();
db.close();
result=true;
SharedUtils.StorePreferences(context, "isStored", true);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
db.close();
result=false;
} catch (IOException e) {
// TODO Auto-generated catch block
db.close();
result=false;
}
return result;
}
/*
* 獲取圖層的類型,-1表示非空間信息,0表示Point,1表示PolyLine,2表示PolyGen
*/
private static int getLayerType(String name)
{
name=name.toLowerCase();
int result=-1;
if(name.contains("point"))
result=0;
else if(name.contains("curve") || name.contains("line") || name.contains("polyline"))
result=1;
else if(name.contains("surface") || name.contains("polygon"))
result=2;
return result;
}
}
package com.gmlmap.readfile;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.gmlmap.activity.Activity_Main;
import com.gmlmap.data.LayerInfo;
import com.gmlmap.util.SharedUtils;
import com.gmlmap.util.SvgUtils;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.widget.Toast;
public class SvgWrite {
private Context context;
private StringBuilder m_buffer = null;
private List m_layerinfos;
private String folderName = "";
public SvgWrite(Context context) {
this.context = context;
}
/*
* 創建文件夾
*/
private void createFolder(String foldername) {
String pathUrl = Environment.getExternalStorageDirectory().getPath()
+ "/GmlParser/" + foldername;
File file = new File(pathUrl);
if (!file.exists())
file.mkdirs();
copy("htmfuc.js", pathUrl);
copy("index.html", pathUrl);
}
/**
*
* @param ASSETS_NAME
* 要復制的文件名
* @param savePath
* 要保存的路徑 testCopy(Context context)是一個測試例子。
*/
private void copy(String ASSETS_NAME, String savePath) {
String filename = savePath + "/" + ASSETS_NAME;
File dir = new File(savePath);
// 如果目錄不中存在,創建這個目錄
if (!dir.exists())
dir.mkdir();
try {
if (!(new File(filename)).exists()) {
InputStream is = context.getResources().getAssets()
.open(ASSETS_NAME);
FileOutputStream fos = new FileOutputStream(filename);
byte[] buffer = new byte[7168];
int count = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
}
fos.close();
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void deleteFile(File file) {
if (file.exists()) { // 判斷文件是否存在
if (file.isFile()) { // 判斷是否是文件
file.delete(); // delete()方法 你應該知道 是刪除的意思;
}
}
}
/*
* 創建文件
*/
public boolean createFile(String foldername) {
boolean result = false;
File fileRoot = new File(Environment.getExternalStorageDirectory()
.getPath() + "/GmlParser");
if (!fileRoot.exists()) {
fileRoot.mkdir();
}
createFolder(foldername);
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + "/GmlParser/" + foldername + "/map.svg");
if (file.exists())
file.delete();
try {
file.createNewFile();
result = true;
} catch (IOException e) {
// TODO Auto-generated catch block
result = false;
}
return result;
}
public Boolean Write() {
boolean result = false;
SvgUtils m_svg = new SvgUtils(context);
AddContent(m_svg.getDocumentStart());
folderName = SharedUtils
.getStringValue(context, "filename", "TestData");
// 打開或創建數據庫
SQLiteDatabase db = context.openOrCreateDatabase(folderName + ".db",
Context.MODE_PRIVATE, null);
if (m_layerinfos == null)
m_layerinfos = new ArrayList();
Cursor c = db.rawQuery(getLinfoSelect(), null);
while (c.moveToNext()) {
LayerInfo ainfo = new LayerInfo();
ainfo.Lid = c.getInt(c.getColumnIndex("Lid"));
ainfo.Lname = c.getString(c.getColumnIndex("Lname"));
ainfo.Ltype = c.getInt(c.getColumnIndex("Ltype"));
Random random = new Random();
ainfo.Lstyle = random.nextInt(3);
m_layerinfos.add(ainfo);
}
c.close();
for (int i = 0; i < m_layerinfos.size(); i++) {
int Lid = m_layerinfos.get(i).Lid;
if (m_layerinfos.get(i).Ltype != -1) {
AddContent(m_svg.SetLayerStart(Lid));
c = db.rawQuery(getPinfoSelect(Lid), null);
while (c.moveToNext()) {
String PosList = c.getString(c.getColumnIndex("Pos"));
AddContent(m_svg.Draw(PosList, m_layerinfos.get(i).Ltype,
m_layerinfos.get(i).Lstyle));
}
c.close();
}
else
{
AddContent(""+m_svg.SetLayerStart(Lid));
c = db.rawQuery(getTinfoSelect(Lid), null);
while (c.moveToNext()) {
String PosList = c.getString(c.getColumnIndex("Pos"));
String Name=c.getString(c.getColumnIndex("Name"));
String Oid="O_"+c.getInt(c.getColumnIndex("Oid"));
AddContent(m_svg.DrawText(PosList, Name,Oid));
}
c.close();
}
AddContent(SvgUtils.SVG_LAYER_ENDTAG);
}
AddContent(SvgUtils.SVG_LAYER_ENDTAG + SvgUtils.SVG_ENDDOUCUMENT);
result = WriteContent(this.m_buffer.toString());
if (result)
SharedUtils.StorePreferences(context, "isSvg", result);
return result;
}
private void AddContent(String str) {
if (m_buffer == null)
m_buffer = new StringBuilder();
m_buffer.append(str);
}
// 向已創建的文件中寫入數據庫中存儲的數據
private boolean WriteContent(String str) {
boolean result = false;
try {
createFile(folderName);
FileWriter fw = null;
BufferedWriter bw = null;
fw = new FileWriter(Environment.getExternalStorageDirectory()
.getPath() + "/GmlParser/" + folderName + "/map.svg", true);//
// 創建FileWriter對象,用來寫入字符流
bw = new BufferedWriter(fw); // 將緩沖對文件的輸出
bw.write(str); // 寫入文件
bw.newLine();
bw.flush(); // 刷新該流的緩沖
bw.close();
fw.close();
result = true;
} catch (IOException e) {
// TODO Auto-generated catch block
result = false;
}
return result;
}
/*
* 獲取圖層信息的select語句
*/
private String getLinfoSelect() {
return "select * from LayersInfo order by Ltype DESC";
}
private String getPinfoSelect(int Lid) {
return "select Pos from FeaturePositon where Lid=" + Lid;
}
//文字
private String getTinfoSelect(int Lid)
{
//String result="select name.TextString Name,pos.Pos Pos from ";
//String name="(Select FeatureId,TextString From L_"+Lid+" ) name,FeaturePositon pos";
//return result+name+"where name.FeatureId=pos.OBJECTID";
return "select name.TextString Name,name.OBJECTID Oid,pos.Pos Pos from (Select OBJECTID,FeatureId,TextString From L_4 ) name,FeaturePositon pos where name.FeatureId=pos.OBJECTID";
}
}
package com.gmlmap.util;
import java.util.Random;
import android.content.Context;
public class SvgUtils {
public static String[] PolygenColors={"#dfeafc","#faf3df","#fce3e3","#fed4cc"};
public static String[] PolylineColors={"#0c343d","#274e13","#783f04","#073763"};
public static String[] PointColors={"#ff0000","#ff9900","#00ff00","#ffff00"};
public static String[] Stroks={"#330000","#003300","#660000","#000080","#FFD700"};
public static String XML_BASE="";
public static String SVG_BASE="
JS文件控制
var htmlObj, SVGDoc, SVGRoot, viewBox, goLeft, goRight, innerSVG;
var currentSize, currentPosition, currentRoomId, currentRoomLabel;
var svgns = "http://www.w3.org/2000/svg";
var S_Width,S_Height;
var curtype=0;
function Init()
{
htmlObj = document.getElementById("map");
SVGDoc = htmlObj.getSVGDocument();
SVGRoot = SVGDoc.documentElement;
S_Width=screen.width;
S_Height=screen.height;
}
function changeVisible(tagname){
var tag=SVGDoc.getElementById(tagname);
if(!tag)
{
return;
}
var visible=tag.getAttribute("visibility");
if(visible=="hidden")
{
tag.setAttribute("visibility","visible");
}
else
{
tag.setAttribute("visibility","hidden");
}
}
function ZoomIn()
{
if(curtype<5)
{
curtype=curtype+1;
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
viewBoxValues[0] = parseFloat(viewBoxValues[0]); // LeftX
viewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpY
viewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdith
viewBoxValues[3] = parseFloat(viewBoxValues[3]);
viewBoxValues[0]=getLower(viewBoxValues[0],viewBoxValues[2],viewBoxValues[2]/2);
viewBoxValues[1]=getLower(viewBoxValues[1],viewBoxValues[3],viewBoxValues[3]/2);
viewBoxValues[2] = viewBoxValues[2]/2;
viewBoxValues[3] = viewBoxValues[3]/2;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
}
function ZoomOut()
{
if(curtype>-2)
{
curtype=curtype-1;
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
viewBoxValues[0] = parseFloat(viewBoxValues[0]); // LeftX
viewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpY
viewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdith
viewBoxValues[3] = parseFloat(viewBoxValues[3]);
viewBoxValues[0]=getLower(viewBoxValues[0],viewBoxValues[2],viewBoxValues[2]*2);
viewBoxValues[1]=getLower(viewBoxValues[1],viewBoxValues[3],viewBoxValues[3]*2);
viewBoxValues[2] = viewBoxValues[2]/0.5;
viewBoxValues[3] = viewBoxValues[3]/0.5;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
}
function getLower(oldLower,oldValue,newValue)
{
return oldLower+oldValue/2-newValue/2;
}
function searchByid(tname)
{
var oElement=SVGDoc.getElementById(tname);
var x=parseFloat(oElement.getAttribute('x'));
var y=parseFloat(oElement.getAttribute('y'));
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
viewBoxValues[2]=parseFloat(viewBoxValues[2]);
viewBoxValues[3]=parseFloat(viewBoxValues[3]);
viewBoxValues[0]=x-viewBoxValues[2]/2;
viewBoxValues[1]=y-viewBoxValues[3]/2;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
function Pan()
{
var panRate = 10;
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
viewBoxValues[0] = parseFloat(viewBoxValues[0]); // LeftX
viewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpY
viewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdith
viewBoxValues[0] += panRate*viewBoxValues[2] /S_Width;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
function scrool(distanceX,distanceY)
{
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
viewBoxValues[0] = parseFloat(viewBoxValues[0]); // LeftX
viewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpY
viewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdith
viewBoxValues[3] = parseFloat(viewBoxValues[3]); // Uheight
viewBoxValues[0] += parseFloat(distanceX)*viewBoxValues[2] /S_Width;
viewBoxValues[1] += parseFloat(distanceY)*viewBoxValues[3] /S_Height;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
function Zoom(x,y)
{
if ( evt.detail ==2 ){
var panRate = 10;
var rootElement=SVGDoc.getElementById("root");
var viewBox = rootElement.getAttribute('viewBox'); // Grab the object representing the SVG element's viewBox attribute.
var viewBoxValues = viewBox.split(',');
x=parseFloat(x);
y=parseFloat(y);
viewBoxValues[0] = parseFloat(viewBoxValues[0]); // LeftX
viewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpY
viewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdith
viewBoxValues[3] = parseFloat(viewBoxValues[3]);
viewBoxValues[0]= getBasecor(getTruecorX(x,viewBoxValues[0],viewBoxValues[2] ),viewBoxValues[2]/2);
viewBoxValues[1]= getBasecor(getTruecorY(y,viewBoxValues[1],viewBoxValues[3] ),viewBoxValues[3]/2);
viewBoxValues[2] = viewBoxValues[2]/2;
viewBoxValues[3] = viewBoxValues[3]/2;
rootElement.setAttribute('viewBox', viewBoxValues.join(','));
}
}
function getTruecorX(CorX,LowerX,Width)
{
return LowerX+Width/S_Width*CorX;
}
function getTruecorY(CorY,LowerY,Height)
{
return LowerY+Height/S_Height*CorY;
}
function getBasecor(Cor,value)
{
return Cor-value/2;
}
參考鏈�
Gml解析並顯示(Android� - 下載頻道 - CSDN.NET
完成,效果如�
搭建react-native for android的windows開發環境移動應用的開發分為ios和android兩個平台,開發一款應用就需要做兩次不同的開發。而rea
如圖所示,有時候為了布局美觀,在搜索時沒有搜索按鈕,而是調用軟件盤上的按鈕。調用的實現只需要在XML在輸入框中加入android:imeOptions=actionSe
不少朋友都用過wifi萬能鑰匙,一般都是用它來獲得免費wifi的。wifi萬能鑰匙手機版是一款自動獲取周邊免費Wi-Fi熱點信息並建立連接的android�
我用GridView來顯示一些字符串,而字符串的長度是不固定的,然後就遇到問題了:有時字符重疊,有時顯示不全,有時兩種問題同時出現。見下圖� 圖一 GridView顯示�