zoukankan      html  css  js  c++  java
  • Android之解析GML并显示

    本例主要实现在APP中解析GML数据并显示

    GML,地理标记语言(外语全称:Geography MarkupLanguage、外语缩写:GML),它由开放式地理信息系统协会(外语缩写:OGC)于1999年提出,并得到了许多公司的大力支持,如Oracle、Galdos、MapInfo、CubeWerx等。GML能够表示地理空间对象的空间数据和非空间属性数据

    实现思路

    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的时候注意下面几个事项就行:

    1. 由于GML文件里面位置数据过大,所以需要在SVG中设置ViewBox保证地图能够全部显示(关于ViewBox也去百度吧)。

    2. 坐标转换,在GML中默认的坐标原点是左下角,而SVG的坐标原点是左上角,这点我想大家都因应该在之前接触过,所以需要进行坐标转换,就是进行垂直翻转而已。最初我使用的方法是将每个坐标的纵坐标变成相反数,然后就导致写SVG文件花了2分钟……。这样当然不行啊,找别的方法吧,后来终于找到个好办法,用矩阵变换,就是SVG里面的matrix属性,一下就变成10s以内,真是……

    3. 图层顺序,写SVG的时候图层显示应该按照面线点文字的顺序,这样可以保证所有图层都能够显示

    参考链接

    理解SVG坐标系统和变换: transform属性 - 推酷

    功能实现

    因为我用的SVG,所以没必要再进行SVG解析,直接用浏览器就可以查看,所以我只需要实现一个浏览器的功能就行了,用WebView控件,由于SVG的放大缩小平移可以用Javascript实现,所以我的所有功能都是在Javascript中的。但是在Android里面直接加载SVG文件会导致Javascript失效,所以用html内联SVG,这个也不再多说,大家参考html文件即可。
    放大缩小:放大缩小的功能就是变化ViewBox即可,大家可以参考文件夹里面的js文件。
    平移:平移功能要重写WebView的ontouch事件,然后再调用Javascript函数,具体也不多说,大家自己看吧。
    搜索:搜索分为两部分,首先是从数据库中按照搜索条件查询出对象的ID,然后调用Javascript搜索的相关函数搜索出SVG中对应的对象。

    参考链接

    Android WebView 开发详解(一) - typename 记录点滴 - 博客频道 - CSDN.NET

    实现

    第一次进入应用时,先解析GML,将数据存储在数据库中,生成SVG,用webView显示HTML来显示SVG,在里面用JS实现一些功能控制,第二次进入时直接加载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;
    
        @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<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); // 创建视图容器并设置上下文
            }
    
            @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;
                }
        }
    
    }

    首先解析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;     //一般情况,不进行任何操作,直接跳
        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;//当前位置
    
            //打开或创建数据库  
            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;
        }
    
    
    }

    生成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;
        }
    
        /*
         * 创建文件夹
         */
        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<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);
        }
    
        // 向已创建的文件中写入数据库中存储的数据
        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";
        }
    }

    其中要用到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;
        }
    
    
        //根据点集确定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:z
              if(i%2==0)
              {
                  double x=Double.parseDouble(poslist[i]);
                  if(i==0)
                     lowerx=x;
                  else
                      lowerx=(lowerx>x)?x:lowerx;
                  upperx=(upperx<x)?x:upperx;
              }
              else
              {
                  double y=Double.parseDouble(poslist[i]);
                  if(i==1)
                      lowery=y;
                  else
                      lowery=(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-1.5" />";
            return result;
        }
    
        public String DrawPolyGen(String Pos,String fillColor,String strokeColor)
        {
            String result="<polygon points=""+Pos+"" style="fill:"+fillColor+";stroke:"+strokeColor+";stroke-1.5"/>";
            return result;
        }
    
        /*
         * 坐标转换
         */
        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]); // 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

    完成,效果如下

    这里写图片描述

  • 相关阅读:
    Linux目录操作
    图形库
    Mybatis两表连接(一对一)
    ssm图片上传到数据库
    ajax函数实例
    html、css基础
    HDU 1213 How Many Tables
    HTML5简介
    在script中创建标签的三种方式
    html css js jq问题总结
  • 原文地址:https://www.cnblogs.com/jjx2013/p/6223692.html
Copyright © 2011-2022 走看看