Android之解析GML并显示
本例主要實現(xiàn)在APP中解析GML數(shù)據(jù)并顯示
GML,地理標(biāo)記語言(外語全稱:Geography MarkupLanguage、外語縮寫:GML),它由開放式地理信息系統(tǒng)協(xié)會(外語縮寫:OGC)于1999年提出,并得到了許多公司的大力支持,如Oracle、Galdos、MapInfo、CubeWerx等。GML能夠表示地理空間對象的空間數(shù)據(jù)和非空間屬性數(shù)據(jù)
實現(xiàn)思路
GML文檔解析
GML文檔的本質(zhì)還是Xml文檔,所以可以用Xml解析器進(jìn)行解析,在Android中可以使用自帶的XmlPullParser進(jìn)行解析,當(dāng)然你也可以用SAX解析器可DOM解析器。在GML文檔中有兩種屬性,一類是空間屬性,另外一個就是非空間屬性。其中空間屬性是至關(guān)重要的,因為要進(jìn)行地圖顯示必須要用空間屬性;而非空間屬性可以不用,但是由于要進(jìn)行查詢操作,所以我將非空間屬性也進(jìn)行存儲。
在讀GML文檔時,首先讀取圖層,然后判斷圖層中的屬性都有哪些,如果是非空間屬性,將其存儲起來(我用的是Sqlite數(shù)據(jù)庫),如果是空間屬性,那么第一個空間屬性肯定是關(guān)于圖層類型的,即他是Polygen,Polyline或是Point,然后在或標(biāo)簽下存儲的位置信息,將位置信息存儲起來即可。
以上就是大致的讀取GML文檔的思路。
地圖顯示
地圖顯示的方法有很多種,我簡單介紹兩種,一種是使用畫布canvas進(jìn)行繪制,另外一種就是使用SVG進(jìn)行顯示。由于我的水平有限,想不出解決canvas加載重繪時卡頓的問題,所以我就使用svg進(jìn)行顯示,使用svg最大的好處就是只在首次使用的時候生成SVG文件而花費的時間較長,而在之后的使用中加載時間在1s以內(nèi);另外就是使用svg進(jìn)行功能實現(xiàn)時不會出現(xiàn)卡頓或者說是卡頓比前一種方法小的多。(在文件夾中包含的使用canvas繪制的工程是我找我的學(xué)長要的,哈哈)。
關(guān)于SVG大家有不明白的直接去百度,那里面比我講的清楚的多,在寫SVG的時候注意下面幾個事項就行:
由于GML文件里面位置數(shù)據(jù)過大,所以需要在SVG中設(shè)置ViewBox保證地圖能夠全部顯示(關(guān)于ViewBox也去百度吧)。
坐標(biāo)轉(zhuǎn)換,在GML中默認(rèn)的坐標(biāo)原點是左下角,而SVG的坐標(biāo)原點是左上角,這點我想大家都因應(yīng)該在之前接觸過,所以需要進(jìn)行坐標(biāo)轉(zhuǎn)換,就是進(jìn)行垂直翻轉(zhuǎn)而已。最初我使用的方法是將每個坐標(biāo)的縱坐標(biāo)變成相反數(shù),然后就導(dǎo)致寫SVG文件花了2分鐘……。這樣當(dāng)然不行啊,找別的方法吧,后來終于找到個好辦法,用矩陣變換,就是SVG里面的matrix屬性,一下就變成10s以內(nèi),真是……
圖層順序,寫SVG的時候圖層顯示應(yīng)該按照面線點文字的順序,這樣可以保證所有圖層都能夠顯示
參考鏈接
理解SVG坐標(biāo)系統(tǒng)和變換: transform屬性 - 推酷
功能實現(xiàn)
因為我用的SVG,所以沒必要再進(jìn)行SVG解析,直接用瀏覽器就可以查看,所以我只需要實現(xiàn)一個瀏覽器的功能就行了,用WebView控件,由于SVG的放大縮小平移可以用Javascript實現(xiàn),所以我的所有功能都是在Javascript中的。但是在Android里面直接加載SVG文件會導(dǎo)致Javascript失效,所以用html內(nèi)聯(lián)SVG,這個也不再多說,大家參考html文件即可。
放大縮小:放大縮小的功能就是變化ViewBox即可,大家可以參考文件夾里面的js文件。
平移:平移功能要重寫WebView的ontouch事件,然后再調(diào)用Javascript函數(shù),具體也不多說,大家自己看吧。
搜索:搜索分為兩部分,首先是從數(shù)據(jù)庫中按照搜索條件查詢出對象的ID,然后調(diào)用Javascript搜索的相關(guān)函數(shù)搜索出SVG中對應(yīng)的對象。
參考鏈接
Android WebView 開發(fā)詳解(一) - typename 記錄點滴 - 博客頻道 - CSDN.NET
實現(xiàn)
第一次進(jìn)入應(yīng)用時,先解析GML,將數(shù)據(jù)存儲在數(shù)據(jù)庫中,生成SVG,用webView顯示HTML來顯示SVG,在里面用JS實現(xiàn)一些功能控制,第二次進(jìn)入時直接加載SVG即可
主Activity
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<LayerInfo> m_layers;@Overrideprotected 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為自己標(biāo)題欄的布局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() {@Overridepublic void onDrawerOpened() {}@Overridepublic void onDrawerClosed() {}});mButton = (TextView) findViewById(R.id.bt_chou);mButton.setOnClickListener(new OnClickListener() {@Overridepublic 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(){@Overridepublic boolean onTouch(View v, MotionEvent event) {// TODO Auto-generated method stubmGestureDetector.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(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubString 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(), "沒有搜索到結(jié)果",Toast.LENGTH_SHORT).show();elsem_webview.loadUrl("javascript:searchByid('"+id+"')");m_edit.setText("");}}});m_btzoomin.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubm_webview.loadUrl("javascript:ZoomIn()");}});m_btzoomout.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubm_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 blockresult = 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解析發(fā)生錯誤", Toast.LENGTH_SHORT).show();break;case 2:Toast.makeText(getApplicationContext(), "Svg生成發(fā)生錯誤", Toast.LENGTH_SHORT).show();break;}dialog.dismiss();}};class mainThread implements Runnable {@Overridepublic void run() {Message msg = handler.obtainMessage();if (GmlRead()) {SvgWrite m_writer = new SvgWrite(Activity_Main.this);if (m_writer.Write())msg.what = 0;// SVG生成成功elsemsg.what = 2;// svg生成失敗} elsemsg.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(), "首次進(jìn)入系統(tǒng)會花費5~20秒的時間進(jìn)行數(shù)據(jù)解析,請勿退出~!",Toast.LENGTH_LONG).show();/*** 進(jìn)度條*/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<LayerInfo> layers;private ArrayList<Boolean> status;private LayoutInflater m_listContainer; // 視圖容器private Context context;class Views{CheckBox m_check;LinearLayout button;}public MAdapter(Context context,ArrayList<LayerInfo> mlayers){this.context=context;layers=mlayers;status=new ArrayList<Boolean>();m_listContainer = LayoutInflater.from(context); // 創(chuàng)建視圖容器并設(shè)置上下文}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn layers.size();}@Overridepublic Object getItem(int arg0) {// TODO Auto-generated method stubreturn layers.get(arg0);}@Overridepublic long getItemId(int arg0) {// TODO Auto-generated method stubreturn arg0;}@Overridepublic View getView(int arg0, View arg1, ViewGroup arg2) {// TODO Auto-generated method stubViews 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() {@Overridepublic void onClick(View v) {m_webview.loadUrl("javascript:changeVisible('L_"+v.getTag()+"')");}});/*m_views.button.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubIntent intent=new Intent(Activity_Main.this,Activity_attr.class);intent.putExtra("name", "L_"+v.getTag());startActivity(intent);}});*/return arg1;}}class MyOnGestureListener extends SimpleOnGestureListener{//滑動 Drag@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {m_webview.loadUrl("javascript:scrool("+distanceX+","+distanceY+")");return false;}@Overridepublic boolean onDoubleTap(MotionEvent e) {m_webview.loadUrl("javascript:ZoomIn()");return false;}//抬起@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onDown(MotionEvent e) {return false;}}}首先解析GML
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; //一般情況,不進(jìn)行任何操作,直接跳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<String> AttrNames=new ArrayList<String>();LayerInfo m_layerinfo=new LayerInfo();PosInfo m_posinfo=new PosInfo();int m_curCondition=CASE_NORMAL;//當(dāng)前位置//打開或創(chuàng)建數(shù)據(jù)庫 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)");//創(chuàng)建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;}elseeventType = 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);}elsem_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;elsem_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();}//關(guān)閉當(dāng)前數(shù)據(jù)庫 db.setTransactionSuccessful(); db.endTransaction(); db.close(); result=true;SharedUtils.StorePreferences(context, "isStored", true);} catch (XmlPullParserException e) {// TODO Auto-generated catch blockdb.close();result=false;} catch (IOException e) {// TODO Auto-generated catch blockdb.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;}}生成SVG
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<LayerInfo> m_layerinfos;private String folderName = "";public SvgWrite(Context context) {this.context = context;}/** 創(chuàng)建文件夾*/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* 要復(fù)制的文件名* @param savePath* 要保存的路徑 testCopy(Context context)是一個測試?yán)印?/private void copy(String ASSETS_NAME, String savePath) {String filename = savePath + "/" + ASSETS_NAME;File dir = new File(savePath);// 如果目錄不中存在,創(chuàng)建這個目錄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()方法 你應(yīng)該知道 是刪除的意思;}} }/** 創(chuàng)建文件*/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 blockresult = 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");// 打開或創(chuàng)建數(shù)據(jù)庫SQLiteDatabase db = context.openOrCreateDatabase(folderName + ".db",Context.MODE_PRIVATE, null);if (m_layerinfos == null)m_layerinfos = new ArrayList<LayerInfo>();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("</g>"+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);}// 向已創(chuàng)建的文件中寫入數(shù)據(jù)庫中存儲的數(shù)據(jù)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);//// 創(chuàng)建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 blockresult = 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";} }其中要用到SvgUtils
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="<?xml version=\"1.0\" encoding=\"utf-8\"?>";public static String SVG_BASE="<svg id=\"root\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" ";public static String SVG_LAYERS="<g id=\"layers\"><g transform=\"matrix(1,0,0,-1,0,0)\">";public static String SVG_LAYER_STARTTAG="<g id=\"L_";public static String SVG_LAYER_ENDTAG="</g>";public static String SVG_ENDDOUCUMENT="</svg>";private double LOWER_X;private double LOWER_Y;private double UPPER_X;private double UPPER_Y;private Context m_context;public SvgUtils(Context context){this.m_context=context;SharedUtils.StorePreferences(context,"lowerCorner","585305.346019984 3338389.98497472");SharedUtils.StorePreferences(context,"upperCorner","596424.775248615 3345263.17995185");String lowerCorner=SharedUtils.getStringValue(m_context, "lowerCorner", "0 0");String upperCorner=SharedUtils.getStringValue(m_context, "upperCorner", "1000 1000");String poslist1[]=lowerCorner.split(" ");String poslist2[]=upperCorner.split(" ");LOWER_X=Double.parseDouble(poslist1[0]);LOWER_Y=Double.parseDouble(poslist1[1]);UPPER_X=Double.parseDouble(poslist2[0]);UPPER_Y=Double.parseDouble(poslist2[1]);}public String getDocumentStart(){return XML_BASE+SVG_BASE+" width=\"100%\" height=\"100%\" viewBox=\""+LOWER_X+",-"+UPPER_Y+","+(UPPER_X-LOWER_X)+","+(UPPER_Y-LOWER_Y)+"\">"+SVG_LAYERS;}public String SetLayerStart(int Lid){return SVG_LAYER_STARTTAG+Lid+"\">";}public String Draw(String PosList,int Ltype,int Lstyle){String result="";switch(Ltype){case 0:result=DrawPoint(PosList,PointColors[Lstyle]);break;case 1:result=DrawPolyLine(PosList,PolylineColors[Lstyle]);break;case 2:{Random random = new Random();result=DrawPolyGen(PosList,PolygenColors[Lstyle],Stroks[ random.nextInt(4)]);}break;}return result;}//根據(jù)點集確定text位置private String getTextPos(String Pos){String result="";double lowerx=0,upperx=0,lowery=0,uppery=0;String[] poslist=Pos.split(" ");for(int i=0;i<poslist.length;i++){//x? y:zif(i%2==0){double x=Double.parseDouble(poslist[i]);if(i==0)lowerx=x;elselowerx=(lowerx>x)?x:lowerx;upperx=(upperx<x)?x:upperx;}else{double y=Double.parseDouble(poslist[i]);if(i==1)lowery=y;elselowery=(lowery>y)?y:lowery;uppery=(uppery<y)?y:uppery;}}result="x=\""+(lowerx+(upperx-lowerx)/4)+"\" y=\"-"+((uppery)-(uppery-lowery)/2)+"\" ";return result;}public String DrawText(String Pos,String name,String Oid){String result="";result="<text id=\""+Oid+"\" "+getTextPos(Pos)+"fill=\"black\" font-size=\"260\">"+name+"</text>";return result;}public String DrawPoint(String Pos,String Color){String Poss[]=Pos.split(" ");String result="<circle cx=\""+Poss[0]+"\" cy=\""+Poss[1]+"\" r=\"15\" fill=\""+Color+"\"/>";return result;}public String DrawPolyLine(String Pos,String lineColor){String result="<polyline points=\" "+Pos+"\" style=\"fill:none;stroke:"+lineColor+";stroke-width:1.5\" />";return result;}public String DrawPolyGen(String Pos,String fillColor,String strokeColor){String result="<polygon points=\""+Pos+"\" style=\"fill:"+fillColor+";stroke:"+strokeColor+";stroke-width:1.5\"/>";return result;}/** 坐標(biāo)轉(zhuǎn)換*/private String convertCoorX(String x){return Double.parseDouble(x)-LOWER_X+"";}private String convertCoorY(String y){return Double.parseDouble(y)-LOWER_Y+"";} }HTML文件
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title> map </title> <script src="htmfuc.js" type="text/javascript" ></script> <style> .div-a{ position:absolute; left:0px; top:0px;background-color:transparent;width:100%; height:100% } </style> </head><body onload="Init()"> <div class="div-a" filter:alpha(opacity=100,finishopacity=0,style=2></div> <embed id="map" src="./map.svg" left="0px" top="0px"; width="100%" height="100%" type="image/svg+xml" > </body> </html>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]); // LeftXviewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpYviewBoxValues[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]); // LeftXviewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpYviewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdithviewBoxValues[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]); // LeftXviewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpYviewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdithviewBoxValues[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]); // LeftXviewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpYviewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdithviewBoxValues[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]); // LeftXviewBoxValues[1] = parseFloat(viewBoxValues[1]); // UpYviewBoxValues[2] = parseFloat(viewBoxValues[2]); // UWdithviewBoxValues[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
完成,效果如下
總結(jié)
以上是生活随笔為你收集整理的Android之解析GML并显示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爆款专栏《Python 黑科技》目录导航
- 下一篇: Android之Intent深入