ucmap for android 使用总结

我从业以来,很长有很多时间都在研究gis。不过是开源的还是收费的,多少多会看。现在又看了国内收费的ucmap for android ,说说我的感受吧。目前来说这是我用过接口最奇怪的,怎么说呢。就是跟一般习惯是不一样的。刚开始你会很纳闷,后面我会解释一下。我先声明,只代表个人观点,只是使用者观点。

1,官网

直接百度搜索ucmap即可,打开他们公司官网。下载开发包。

UCMap(V6.6.0)Android.7z:下载开发包,然后是他们公司的官网的论坛,有帖子申请实用码,说是3个月。说起试用码,我就要吐槽了。这个试用码是指定机器的,麻烦。这个码还有问题,我用了不到3个月。demo弹出来的码居然变了,跟我之前申请用的居然不一样了。因为我也做过一些注册码机制类似。这种形式最不好用。说到这里,因为我手机的机器码变了,现在没有码,这篇博客就不贴相关地图的界面,因为会崩溃,也没什么用。

UCMap(V7.0.0)Android.7z:最新版本android的开发包sdk 7.0已经不用试用码(之前的版本都需要)。现在做成跟arcgis 一样,有水印和法律声明。自已下载开发包,里面pdf以及demo,还有接口中文说明都有。这点是比较好的。

这里我就要说一下国内的另外一家超图公司的,那个试用码是3个月,不指定机器。而且是发送到申请邮箱。就是方便。

还有一家arcgis for android。国外的最大型的,开发gis都知道。这个更好,不用码,只不过有水印,还有版权声明。这个形式也挺好的。这个我只是总结现象。

至于开发包就大家自已去下载吧。

2,加载地图


这是一个官方提供的加载地图的形式。我贴一下主要代码:

        mapView = (MapView) findViewById(R.id.mapView);
        mapView.setListener(new IMapViewListener() {

            @Override
            public void onSizeChanged(int w, int h, int oldw, int oldh) {
                MapControl mapControl = mapView.getMapControl();
                mapControl.showScaleBar(8, getResources().getDisplayMetrics().xdpi / 2.54f, 10, mapControl.getHeight() - 10, Color.BLACK, Color.RED, 3, 20);
                if (mapControl.getMap() == null) {
                    String path = Environment.getExternalStorageDirectory().getPath();
                    if (!new File(path + "/" + workspace + "/map.ini").exists())//这里检查是否具有这个地图,没有则新建
                        App.getInstance().createMap(path + "/" + workspace);
                    mapControl.loadMap(path + "/" + workspace + "/map.ini", (byte) 0);//装载地图
                    mapControl.setPanTool();
                }
            }

        });
这是一个离线地图,看以看出这个是加载根目录下面的bj2文件夹下面的map.ini。如果你测试出现崩溃或者没有地图,那么你自已留意吧。

这个数据是shp数据转换出来的数据库。我们看加载文件就知道。map.ini其实是个配置文件,用记事本打开就知道。有点长,下面我就展示部分。

[Map]
labelColor=0,0,0
LabelStyleCount=0
XMin=116.275146484375
YMin=39.864261627197266
XMax=116.45286494082686
YMax=39.97161865234375
LayerCount=23
[FixedShapefileLayer]0  省界_region  5
MinScale=0.0
MaxScale=0.0
Valid=1
Visible=1
Name=省界_region
Selectable=1
ScaleSymbols=0
[SimpleRenderer]
[FillSymbol]
FillColor_255=153,153,0
OutlineWidth=0.0
OutlineColor_255=153,153,0
然后我们可以在这里找到map.dat 。官方开发包里面都有,不要问我哪里来的数据。bj2文件下面。

用一个可视化sqlite工具打开


这里可以看出每一条数据,都是有一个范围xmin,ymin,xmax,ymax。然后是data,这个就是一系列坐标在里面。大家都知道一个线,面都是由很多坐标组成,那么都在里面了。然后外面是个范围。

研究这个呢?一定要对shp数据文件结构比较了解。这个shp里面东西。相当于把shp数据转换成这个表。

还有还有dbf属性文件转换成一张表的。其实在里面都能找到。

2,加载shp


说起加载shp,应该都是gis当中必备基础功能。上面都看到我解释那个map.ini和map.dat 其实就是shp文件转换出来,有桌面端工具转,也可以用java代码直接转。生成那两个东西。

        mapView = (MapView) findViewById(R.id.mapView);

        mapView.setListener(new IMapViewListener() {
            @Override
            public void onSizeChanged(int w, int h, int oldw, int oldh) {
                MapControl mapControl = mapView.getMapControl();
                mapControl.showScaleBar(8, getResources().getDisplayMetrics().xdpi / 2.54f, 10, mapControl.getHeight() - 10, Color.BLACK, Color.RED, 3, 20);
                if (mapControl.getMap() == null) {

                    String path = Environment.getExternalStorageDirectory().getPath();
                    if (!new File(path + "/shape/map.ini").exists())
                        App.getInstance().createMap(path + "/shape");
                    mapControl.loadMap(path + "/shape/map.ini", (byte) 0);
                    String pathname = path + "/shape/DLTB.shp";
                    ShapefileLayer slayer = ShapefileLayer.createFromSHP(
                            (short) mapControl.getMap().getLayerCount(),
                            pathname, 100000, 0, true, true, new SimpleRenderer("", "", new FillSymbol(0xFF00FF00, null)), "GBK");
                    if (slayer != null) {
                        mapControl.getMap().addLayer(slayer);
                        mapControl.getDisplay().getDisplayTransformation().setVisibleBounds(mapControl.getFullExtent());
                        mapControl.rewriteIni();
                        mapControl.refresh();
                    }
                    //经测试,这个没有调用是很卡顿的
                    //将当前的地图工具设置为移动地图工具
                    mapControl.setPanTool();
                }
            }

        });
第一次加载和转一定会卡在哪里,要做进度条的。因为那都是耗时。在动一下程序就无响应了。

其实有耐心的人,都看到了这个两个类基本上是一样的。第一个是直接加载转换好的shp,一个是在android端写代码加载。

那为什么分两个类,都是继承mapview这个类呢。这就是难用地方之一。所有加载地图都是这样写的

        mapView.setListener(new IMapViewListener() {

            @Override
            public void onSizeChanged(int w, int h, int oldw, int oldh) {
                MapControl mapControl = mapView.getMapControl();
                mapControl.showScaleBar(8, getResources().getDisplayMetrics().xdpi / 2.54f, 10, mapControl.getHeight() - 10, Color.BLACK, Color.RED, 3, 20);
                if (mapControl.getMap() == null) {

                    mapControl.setPanTool();
                }
            }

        });
这个mapcontrol也是很重要的。自已体会吧。

3,加载谷歌在线地图


这个是demo 1里面功能。

public class MyMapView extends MapView {

	GPSCustomDraw gpsCustomDraw;
	
	public MyMapView(Context context, AttributeSet attrs) {
		super(context, attrs);

	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		if (this.isInEditMode()) return;
		MapControl mapControl=getMapControl();
		gpsCustomDraw = new GPSCustomDraw(mapControl);
		
		//以下代码会在地图窗口的左下角显示一个比例尺符号,具体参数说明请参考doc
		//getResources().getDisplayMetrics().xdpi 获取了屏幕的横向dpi,乘以2.54可以得到1厘米有多少个像素点
		mapControl.showScaleBar(8, getResources().getDisplayMetrics().xdpi/2.54f, 10, mapControl.getHeight()-10, Color.BLACK,Color.RED,3,20);
		if (mapControl.getMap()==null)
		{
			String path=Environment.getExternalStorageDirectory().getPath();
			MapLoader.loadMapXML(mapControl, path+"/OpenSourceMap.xml");
			//MapLoader.loadMapXML(mapControl,Environment.getExternalStorageDirectory().getPath()+"/cache/OpenSourceMapWithLocal.xml",null,1,0.00001f,true);
			mapControl.setCustomDraw(gpsCustomDraw);
			mapControl.setPanTool();
			((OpenSourceMapLayer)mapControl.getMap().getLayer(0)).openZoomInMode();
			mapControl.refresh();
		}
	}

	public void close() {
		if(gpsCustomDraw != null){
			gpsCustomDraw.close();
		}
	}
}
activity调用如下:
package cn.creable.android.demo.activity;

import java.util.Vector;

import cn.creable.android.demo.CopyFileManage;
import cn.creable.android.demo.R;
import cn.creable.android.demo.online.GPSCustomDraw;
import cn.creable.android.demo.online.MyMapView;
import cn.creable.android.demo.online.PathTool;
import cn.creable.android.demo.online.PointTool;
import cn.creable.gridgis.controls.App;
import cn.creable.gridgis.controls.CustomDrawGeometrySelector;
import cn.creable.gridgis.controls.ICustomDraw;
import cn.creable.gridgis.controls.ICustomDrawDataCenter;
import cn.creable.gridgis.controls.MapView;
import cn.creable.gridgis.geometry.IEnvelope;
import cn.creable.gridgis.geometry.IPoint;
import cn.creable.gridgis.geometry.Point;
import cn.creable.ucmap.ILocalSearchListener;
import cn.creable.ucmap.IPathSearchListener;
import cn.creable.ucmap.MapLoader;
import cn.creable.ucmap.OpenSourceMapLayer;
import cn.creable.ucmap.OpenSourceMapLayer.Path;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MapMainActivity extends Activity {
    MyMapView mapView;
    ProgressDialog dlg;
    Activity act;
    PathTool pathTool;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String path = Environment.getExternalStorageDirectory().getPath();
        CopyFileManage.copyAssetsFiletoDirectory(getAssets(), "xml", path);
        setContentView(R.layout.map_main);

        pathTool = null;
        act = this;
        mapView = (MyMapView) findViewById(R.id.mapView);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(Menu.NONE, Menu.NONE, 0, "装入地图");
        menu.add(Menu.NONE, Menu.NONE, 1, "放大地图");
        menu.add(Menu.NONE, Menu.NONE, 2, "缩小地图");
        menu.add(Menu.NONE, Menu.NONE, 3, "平移地图");
        menu.add(Menu.NONE, Menu.NONE, 12, "点击查询坐标");
        menu.add(Menu.NONE, Menu.NONE, 10, "用代码控制视图");
        menu.add(Menu.NONE, Menu.NONE, 11, "查看gps点");
        menu.add(Menu.NONE, Menu.NONE, 4, "关键字查询");
        menu.add(Menu.NONE, Menu.NONE, 5, "路径查询");
        menu.add(Menu.NONE, Menu.NONE, 6, "切换地图数据源");
        menu.add(Menu.NONE, Menu.NONE, 7, "切换地图模式");
        menu.add(Menu.NONE, Menu.NONE, 8, "退出");
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 0:    //装入地图
                MapLoader.loadMapXML(mapView.getMapControl(), "/sdcard/OpenSourceMap.xml");
                mapView.getMapControl().setCustomDraw(new GPSCustomDraw(mapView.getMapControl()));
                mapView.getMapControl().setPanTool();
                break;
            case 1:    //放大地图
                mapView.getMapControl().setZoomInTool();
                break;
            case 2:    //缩小地图
                mapView.getMapControl().setZoomOutTool();
                break;
            case 3:    //平移地图
                mapView.getMapControl().setPanTool();
                break;
            case 10://用代码视图控制
            {
                mapView.getMapControl().getDisplay().getDisplayTransformation().setZoom(10);//直接设置显示比例尺,实现放大到想要的比例,如果仅仅需要居中,可以注释掉这一行
                //以下代码实现以(117,30)为中心居中
                OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                Point pt = oslayer.fromLonLat(117, 30);
                Point offset = oslayer.getOffset(117, 30);
                pt.setX(pt.getX() + offset.getX());
                pt.setY(pt.getY() + offset.getY());
                IEnvelope env = mapView.getMapControl().getExtent();//TODO:注意,如果你需要移动中心点时并setZoom,getExtent必须在setZoom之后调用才行
                env.centerAt(pt);
                mapView.getMapControl().refresh(env);
                break;
            }
            case 4:    //关键字查询
                if (mapView.getMapControl().getMap().getLayerCount() > 0) {
                    OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                    oslayer.setLocalSearchListener(new ILocalSearchListener() {

                        @Override
                        public void localSearchFinished(Vector pois) {
                            if (pois == null) return;
                            int size = pois.size();
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < size; ++i) {
                                OpenSourceMapLayer.POI poi = (OpenSourceMapLayer.POI) pois.get(i);
                                sb.append(poi.title);
                                sb.append("\n");
                            }
                            sb.deleteCharAt(sb.length() - 1);
                            //利用Toast显示查询到的信息点的名字
                            Bundle b = new Bundle();
                            b.putString("string", sb.toString());
                            Message msg = new Message();
                            msg.what = 1;
                            msg.setData(b);
                            handler.sendMessage(msg);
                            sb = null;
                        }

                    });
                    oslayer.localSearch("南京,中山", 0);
                    //显示等待界面
                    dlg = new ProgressDialog(act);
                    dlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    dlg.setTitle("提示");
                    dlg.setMessage("正在进行关键字查询,请稍后");
                    dlg.setIcon(R.drawable.icon);
                    dlg.setIndeterminate(false);
                    dlg.setCancelable(true);
                    dlg.setButton("取消 ", new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                            oslayer.cancel();
                        }

                    });
                    dlg.show();
                }
                break;
            case 5:    //路径查询
                if (mapView.getMapControl().getMap().getLayerCount() > 0) {
                    OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                    if (pathTool == null) {
                        pathTool = new PathTool(mapView.getMapControl(), oslayer, act);
                        mapView.getMapControl().addCustomDraw(pathTool);
                    }
                    mapView.getMapControl().setCurrentTool(pathTool);
                    mapView.getMapControl().refresh();
                }
                break;
            case 6:    //切换地图数据源
                if (mapView.getMapControl().getMap().getLayerCount() > 0) {
                    OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                    switch (oslayer.getMapMode()) {
                        case GOOGLE:
                            oslayer.setMapMode(1);
                            break;
                        case BING:
                            oslayer.setMapMode(0);
                            break;
                    }
                    mapView.getMapControl().refresh();
                }
                break;
            case 7:    //切换地图模式
                if (mapView.getMapControl().getMap().getLayerCount() > 0) {
                    OpenSourceMapLayer oslayer = (OpenSourceMapLayer) mapView.getMapControl().getMap().getLayer(0);
                    switch (oslayer.getMode()) {
                        case 0:
                            oslayer.setMode(1);
                            break;
                        case 1:
                            oslayer.setMode(0);
                            break;
                    }
                    mapView.getMapControl().refresh();
                }
                break;
            case 8:    //退出
                System.exit(0);
                break;
            case 11:
                ICustomDraw draw = mapView.getMapControl().getCustomDraw();
                if (draw != null && draw instanceof ICustomDrawDataCenter) {
                    CustomDrawGeometrySelector s = new CustomDrawGeometrySelector(mapView.getMapControl(), (ICustomDrawDataCenter) draw);
                    s.setOffset(0, 60);
                    mapView.getMapControl().setCurrentTool(s);
                }
                break;
            case 12:
                mapView.getMapControl().setCurrentTool(new PointTool(mapView.getMapControl()));
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    //关闭等待界面
                    dlg.cancel();
                    dlg = null;
                    //利用Toast显示查询的结果
                    Toast.makeText(App.getInstance(), msg.getData().getString("string"), Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    };

    @Override
    protected void onDestroy(){
        if(mapView != null && mapView.getMapControl() != null){
            mapView.getMapControl().closeMap();
            mapView.close();
        }
        super.onDestroy();
    }
}
自已看怎样放配置文件吧:就是谷歌地址解析的文件。


官方demo 有所说明,怎么放在sd卡存储目录。

还有加载天地图,demo里面没有,暂时不知道怎么实现。

4,demo4 功能

这里面功能主要是对shp转换出来的sql进行编辑了。我写很多注释。

        menuGrid.setOnItemClickListener(new AdapterView.OnItemClickListener()

                                        {

                                            @Override
                                            public void onItemClick(AdapterView<?> adapter, View view, int cmd,
                                                                    long arg3) {
                                                menuDialog.dismiss();
                                                switch (cmd) {
                                                    case 0://添加要素
                                                    {
                                                        AlertDialog.Builder builder = new AlertDialog.Builder(act);
                                                        builder.setTitle("请选择图层:");
                                                        layers.clear();
                                                        Vector<String> strs = new Vector<String>();
                                                        //查找当前所有的图层
                                                        int count = mapView.getMapControl().getMap().getLayerCount();
                                                        for (int i = 0; i < count; ++i) {
                                                            ILayer layer = mapView.getMapControl().getMap().getLayer(i);
                                                            if (layer instanceof ShapefileLayer) {
                                                                strs.addElement(layer.getName());
                                                                layers.addElement((ShapefileLayer) layer);
                                                            }
                                                        }
                                                        String[] layerNames = new String[strs.size()];
                                                        strs.copyInto(layerNames);
                                                        strs = null;
                                                        //弹出图层选择的列表对话框
                                                        builder.setSingleChoiceItems(layerNames, -1, new DialogInterface.OnClickListener() {

                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) {
                                                                dialog.cancel();
                                                                //添加要素工具,可以利用该地图工具实现添加点、线、面要素的功能
                                                                AddFeatureTool tool = new AddFeatureTool(mapView.getMapControl(), layers.elementAt(which));
                                                                editTool = tool;
                                                                //设置偏移量,将用户输入的光标从手指下面移动到其他的地方,这样避免光标被用户手指挡住的问题
                                                                //就是捕捉上面一个按钮
                                                                tool.setOffset(0, 60);
                                                                //开启捕捉功能
                                                                tool.openSnap();
                                                                //设置编辑监听器 IEditListener 的监听回调
                                                                editTool.setListener(act);
                                                                //设置当前地图工具
                                                                mapView.getMapControl().setCurrentTool(tool);
                                                            }
                                                        });
                                                        AlertDialog dialog = builder.create();
                                                        dialog.show();
                                                        break;
                                                    }
                                                    case 1: //添加要素 打点
                                                    {
                                                        AlertDialog.Builder builder = new AlertDialog.Builder(act);
                                                        builder.setTitle("请选择图层:");
                                                        layers.clear();
                                                        Vector<String> strs = new Vector<String>();
                                                        //查找当前所有的图层
                                                        int count = mapView.getMapControl().getMap().getLayerCount();
                                                        for (int i = 0; i < count; ++i) {
                                                            ILayer layer = mapView.getMapControl().getMap().getLayer(i);
                                                            if (layer instanceof ShapefileLayer) {
                                                                strs.addElement(layer.getName());
                                                                layers.addElement((ShapefileLayer) layer);
                                                            }
                                                        }
                                                        String[] layerNames = new String[strs.size()];
                                                        strs.copyInto(layerNames);
                                                        strs = null;
                                                        //弹出图层选择的列表对话框
                                                        builder.setSingleChoiceItems(layerNames, -1, new DialogInterface.OnClickListener() {

                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) {
                                                                dialog.cancel();
                                                                //添加要素工具,可以利用该地图工具实现添加点、线、面要素的功能
                                                                AddFeatureTool2 tool = new AddFeatureTool2(mapView.getMapControl(), layers.elementAt(which), ((BitmapDrawable) App.getInstance().getResources().getDrawable(R.drawable.cross)).getBitmap());
                                                                editTool = tool;
                                                                //设置编辑监听器 IEditListener 的监听回调
                                                                editTool.setListener(act);
                                                                //设置当前地图工具
                                                                mapView.getMapControl().setCurrentTool(tool);
                                                                //重画,将缓冲在内存中的地图再次绘制到屏幕上
                                                                mapView.getMapControl().repaint();
                                                            }
                                                        });
                                                        AlertDialog dialog = builder.create();
                                                        dialog.show();
                                                        break;
                                                    }
                                                    case 2: //删除要素
                                                    {
                                                        //删除要素工具,利用本工具可以删除矢量地图上的任何要素
                                                        DeleteFeatureTool tool = new DeleteFeatureTool(mapView.getMapControl());
                                                        //设置偏移量,将用户输入的光标从手指下面移动到其他的地方,这样避免光标被用户手指挡住的问题
                                                        //就是捕捉上面一个按钮
                                                        tool.selector.setOffset(0, 80);
                                                        editTool = tool;
                                                        //设置编辑监听器 IEditListener 的监听回调
                                                        editTool.setListener(act);
                                                        //设置当前地图工具
                                                        mapView.getMapControl().setCurrentTool(tool);
                                                        break;
                                                    }
                                                    case 3: //提交编辑
                                                    {
                                                        editTool.submit();
                                                        break;
                                                    }
                                                    case 4: //修改节点
                                                    {
                                                        //编辑要素工具,使用本工具可以实现对点、线、面地图要素的编辑
                                                        EditFeatureTool editTool = null;
                                                        if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof EditFeatureTool) {
                                                            //获取地图当前的地图工具
                                                            editTool = (EditFeatureTool) mapView.getMapControl().getCurrentTool();
                                                        } else {
                                                            editTool = new EditFeatureTool(mapView.getMapControl());
                                                            //设置一个编辑要素工具
                                                            mapView.getMapControl().setCurrentTool(editTool);
                                                        }
                                                        //设置偏移量,设置放大镜的偏移量
                                                        editTool.selector.setOffset(0, 80);
                                                        //设置编辑类型 Type_MoveNode移动节点
                                                        editTool.setType(EditFeatureTool.Type_MoveNode);
                                                        //IEditListener 的监听回调
                                                        editTool.setListener(act);
                                                        break;
                                                    }
                                                    case 5: //添加节点
                                                    {
                                                        //编辑要素工具,使用本工具可以实现对点、线、面地图要素的编辑
                                                        EditFeatureTool editTool = null;
                                                        if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof EditFeatureTool) {
                                                            //获取地图当前的地图工具
                                                            editTool = (EditFeatureTool) mapView.getMapControl().getCurrentTool();
                                                        } else {
                                                            editTool = new EditFeatureTool(mapView.getMapControl());
                                                            //设置一个编辑要素工具
                                                            mapView.getMapControl().setCurrentTool(editTool);
                                                        }
                                                        //设置偏移量,设置放大镜的偏移量
                                                        editTool.selector.setOffset(0, 80);
                                                        //设置编辑类型 Type_AddNode 添加节点
                                                        editTool.setType(EditFeatureTool.Type_AddNode);
                                                        break;
                                                    }
                                                    case 6: //删除节点
                                                    {
                                                        //编辑要素工具,使用本工具可以实现对点、线、面地图要素的编辑
                                                        EditFeatureTool editTool = null;
                                                        if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof EditFeatureTool) {
                                                            //获取地图当前的地图工具
                                                            editTool = (EditFeatureTool) mapView.getMapControl().getCurrentTool();
                                                        } else {
                                                            editTool = new EditFeatureTool(mapView.getMapControl());
                                                            //设置一个编辑要素工具
                                                            mapView.getMapControl().setCurrentTool(editTool);
                                                        }
                                                        //设置偏移量,设置放大镜的偏移量
                                                        editTool.selector.setOffset(0, 80);
                                                        //设置编辑类型 Type_DeleteNode 删除节点
                                                        editTool.setType(EditFeatureTool.Type_DeleteNode);
                                                        break;
                                                    }
                                                    case 7: //整体移动
                                                    {
                                                        //将前三个层设置为不可选择
                                                        int layerCount = mapView.getMapControl().getMap().getLayerCount();
                                                        if (layerCount > 3) layerCount = 3;
                                                        for (int i = 0; i < layerCount; ++i) {
                                                            ShapefileLayer layer = null;
                                                            if (mapView.getMapControl().getMap().getLayer(i) instanceof ShapefileLayer)
                                                                layer = (ShapefileLayer) mapView.getMapControl().getMap().getLayer(i);
                                                            if (layer != null) {
                                                                //设置是否可以选择  false不可选择
                                                                layer.setSelectable(false);
                                                            }
                                                        }

                                                        //编辑要素工具,使用本工具可以实现对点、线、面地图要素的编辑
                                                        EditFeatureTool tool = new EditFeatureTool(mapView.getMapControl());
                                                        //设置编辑类型 Type_Move 整体移动
                                                        tool.setType(EditFeatureTool.Type_Move);
                                                        //设置当前地图工具
                                                        mapView.getMapControl().setCurrentTool(tool);
                                                        break;
                                                    }
                                                    case 8: //undo
                                                    {
                                                        boolean ret = false;
                                                        if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof IEditTool)
                                                            ret = ((IEditTool) (mapView.getMapControl().getCurrentTool())).undo();
                                                        if (ret == false) {
                                                            ShapefileLayer.undo();
                                                            mapView.getMapControl().refresh();
                                                        }
                                                        break;
                                                    }
                                                    case 9: //redo
                                                    {
                                                        boolean ret = false;
                                                        if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof IEditTool)
                                                            ret = ((IEditTool) (mapView.getMapControl().getCurrentTool())).redo();
                                                        if (ret == false) {
                                                            ShapefileLayer.redo();
                                                            mapView.getMapControl().refresh();
                                                        }
                                                        break;
                                                    }
                                                    case 10://修改属性
                                                    {
                                                        //编辑属性,只是闪烁
                                                        EditFeatureAttTool tool = new EditFeatureAttTool(mapView.getMapControl());
                                                        tool.selector.setOffset(0, 80);
                                                        editTool = tool;
                                                        editTool.setListener(act);
                                                        mapView.getMapControl().setCurrentTool(tool);
                                                        break;
                                                    }
                                                    case 11://地图浏览
                                                        //将当前的地图工具设置为移动地图工具
                                                        mapView.getMapControl().setPanTool();
                                                        break;
                                                    case 12: //导出地图
                                                    {
                                                        AlertDialog.Builder builder = new AlertDialog.Builder(act);
                                                        builder.setTitle("请选择图层:");
                                                        layers.clear();
                                                        Vector<String> strs = new Vector<String>();
                                                        int count = mapView.getMapControl().getMap().getLayerCount();
                                                        for (int i = 0; i < count; ++i) {
                                                            ILayer layer = mapView.getMapControl().getMap().getLayer(i);
                                                            if (layer instanceof ShapefileLayer) {
                                                                strs.addElement(layer.getName());
                                                                layers.addElement((ShapefileLayer) layer);
                                                            }
                                                        }
                                                        String[] layerNames = new String[strs.size()];
                                                        strs.copyInto(layerNames);
                                                        strs = null;

                                                        //对话框对那个图层列表进行选择导出
                                                        builder.setSingleChoiceItems(layerNames, -1, new DialogInterface.OnClickListener() {

                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) {
                                                                dialog.cancel();
                                                                //导出到根目录
                                                                layers.elementAt(which).outputToShapefile("/sdcard/");
                                                                Toast.makeText(act, "导出完成!", Toast.LENGTH_LONG).show();
                                                            }
                                                        });
                                                        AlertDialog dialog = builder.create();
                                                        dialog.show();
                                                        break;
                                                    }
                                                    case 13://开启捕捉
                                                        if (editTool instanceof AddFeatureTool) {
                                                            ((AddFeatureTool) editTool).openSnap();
                                                        } else if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof EditFeatureTool) {
                                                            ((EditFeatureTool) mapView.getMapControl().getCurrentTool()).openSnap();
                                                        }
                                                        break;
                                                    case 14://关闭捕捉
                                                        if (editTool instanceof AddFeatureTool) {
                                                            ((AddFeatureTool) editTool).closeSnap();
                                                        } else if (mapView.getMapControl().getCurrentTool() != null && mapView.getMapControl().getCurrentTool() instanceof EditFeatureTool) {
                                                            ((EditFeatureTool) mapView.getMapControl().getCurrentTool()).closeSnap();
                                                        }
                                                        break;
                                                    case 15://信息工具
                                                        //信息工具,用于显示地图要素的详细属性信息
                                                        //如果是shp文件,那就是dbf属性信息
                                                        InfoTool tool = new InfoTool(mapView.getMapControl(), new IInfoToolListener() {
                                                            @Override
                                                            public void notify(MapControl mapControl, IFeatureLayer flayer,
                                                                               IFeature ft, String[] fields, String[] values) {

                                                                if (ft.getShape().getGeometryType() == GeometryType.Polygon) {
                                                                    //以下代码实现  仅仅闪烁面要素边框的效果
                                                                    Polygon pg = (Polygon) ft.getShape();
                                                                    LinearRing ring = (LinearRing) pg.getExteriorRing();
                                                                    LineString line = new LineString(ring.getPoints());//根据面的边框构造一个线
                                                                    LineSymbol ls = new LineSymbol(3, 0xFFFF0000);//构造一个线样式
                                                                    Vector<IGeometry> geos = new Vector<IGeometry>();
                                                                    geos.add(line);
                                                                    Vector<ISymbol> syms = new Vector<ISymbol>();
                                                                    syms.add(ls);
                                                                    mapControl.flashFeatures(geos, syms, 10);//调用闪烁接口,并只闪烁10次,如果需要无限制的闪烁,请将10改成-1
                                                                } else
                                                                    mapControl.flashFeatures(flayer, ft.getOid());//闪烁被选中的地图要素
                                                                //显示地图要素的属性
                                                                StringBuilder sb = new StringBuilder();
                                                                for (int i = 0; i < fields.length; ++i) {
                                                                    sb.append(fields[i]);
                                                                    sb.append(":");
                                                                    sb.append(values[i]);
                                                                    sb.append("\n");
                                                                }
                                                                sb.deleteCharAt(sb.length() - 1);
                                                                //利用Toast显示地图要素的属性
                                                                if (myt != null) {
                                                                    myt.cancel();
                                                                    myt = null;
                                                                }
                                                                myt = new MyToast(App.getInstance().getApplicationContext());
                                                                myt.setText(sb.toString());
                                                                myt.show();
                                                                //Toast.makeText(App.getInstance(), sb.toString(), Toast.LENGTH_SHORT).show();
                                                                sb = null;
                                                            }

                                                        });
                                                        tool.selector.setOffset(0, 80);
                                                        mapView.getMapControl().setCurrentTool(tool);
                                                        break;
                                                    case 16://投影变换
                                                        //这个被注释掉的是大地2000投影的定义
                                                        //String CGCS2000_3_Degree_GK_Zone_40="+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs";
                                                        String proj1 = ProjectFactory.createWGS84();
                                                        String proj2 = ProjectFactory.createGaussKruger(114, 0, ProjectFactory.ellps_xian1980, 500000, "m");
                                                        SpatialReference sr = new SpatialReference(proj1, proj2);
                                                        sr.addPoint(new Point(113.82133, 23.27463));
                                                        sr.addPoint(new Point(113.82233, 23.27563));
                                                        sr.addPoint(new Point(113.82333, 23.27663));
                                                        sr.addPoint(new Point(113.82433, 23.27763));
                                                        double[] result = sr.pj1Topj2();
                                                        String msg = String.format("经纬度点(113.82133,23.27463)转换到3度带高斯80坐标系之后的坐标为(%f,%f)", result[0], result[1]);
                                                        Toast.makeText(App.getInstance(), msg, Toast.LENGTH_LONG).show();
                                                        break;
                                                    case 17://测距离
                                                        MeasureTool mtool = new MeasureTool(mapView.getMapControl(), 0);
                                                        mtool.setListener(new IMeasureToolListener() {

                                                            @Override
                                                            public void notify(int type, double value) {
                                                                Toast.makeText(App.getInstance(), String.format("距离为:%f米", value), Toast.LENGTH_LONG).show();
                                                            }

                                                        });
                                                        mtool.selector.setOffset(0, 80);
                                                        mapView.getMapControl().setCurrentTool(mtool);
                                                        break;
                                                    case 18://测面积
                                                        MeasureTool mtool1 = new MeasureTool(mapView.getMapControl(), 1);
                                                        mtool1.setListener(new IMeasureToolListener() {

                                                            @Override
                                                            public void notify(int type, double value) {
                                                                Toast.makeText(App.getInstance(), String.format("面积为:%f平方米", value), Toast.LENGTH_LONG).show();
                                                            }

                                                        });
                                                        mtool1.selector.setOffset(0, 80);
                                                        mapView.getMapControl().setCurrentTool(mtool1);
                                                        break;
                                                    case 19: //专题图
                                                    {
                                                        //缩放到能够看到专题图效果的比例尺
                                                        mapView.getMapControl().getDisplay().getDisplayTransformation().setZoom(0.00805f);
                                                        //将第三个图层“县界”的renderer替换为MyRenderer
                                                        IShapefileLayer layer = (IShapefileLayer) mapView.getMapControl().getMap().getLayer(2);
                                                        MyRenderer renderer = new MyRenderer(layer);
                                                        IFeatureLayer flayer = (IFeatureLayer) layer;
                                                        flayer.setRenderer(renderer);
                                                        mapView.getMapControl().refresh();//刷新地图
                                                        break;
                                                    }
                                                    case 20://图层控制
                                                        //其实就是图层的筛选而已
                                                        //遍历当前地图的所有图层
                                                        int cur = -1;
                                                        IMap map = mapView.getMapControl().getMap();
                                                        int size = map.getLayerCount();
                                                        layers2.clear();
                                                        //float curZoom=mapView.getMapControl().getDisplay().getDisplayTransformation().getZoom();
                                                        ILayer layer = null;
                                                        for (int i = 0; i < size; ++i) {
                                                            layer = map.getLayer(i);
                                                            //if (layer.getMinimumScale()<curZoom && curZoom<layer.getMaximumScale())//只有图层的显示比例范围包含了当前显示比例,才可以控制该图层是否可见
                                                            {
                                                                layers2.add(layer);
                                                            }
                                                        }
                                                        size = layers2.size();
                                                        //if (size==0) super.onOptionsItemSelected(item);
                                                        //将图层的名字和图层是否可见,复制进2个数组里,供显示对话框使用
                                                        String[] layerNames = new String[size];
                                                        visible = new boolean[size];
                                                        for (int i = 0; i < size; ++i) {
                                                            layer = layers2.get(i);
                                                            layerNames[i] = layer.getName();
                                                            visible[i] = layer.getVisible();
                                                        }
                                                        //显示一个对话框,供用户控制图层
                                                        AlertDialog.Builder builder = new AlertDialog.Builder(act);
                                                        builder.setIcon(R.drawable.icon);
                                                        builder.setTitle("图层控制");
                                                        builder.setMultiChoiceItems(layerNames, visible, new DialogInterface.OnMultiChoiceClickListener() {

                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
                                                                visible[which] = isChecked;//保存用户的选择
                                                            }
                                                        });
                                                        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {

                                                            @Override
                                                            public void onClick(DialogInterface arg0, int arg1) {
                                                                int size = visible.length;
                                                                for (int i = 0; i < size; ++i) {//重新设置每个可以被控制的图层的可见性
                                                                    layers2.get(i).setVisible(visible[i]);
                                                                }
                                                                mapView.getMapControl().refresh();//刷新地图立即看到效果
                                                            }
                                                        });
                                                        builder.setNegativeButton("取消", null);//取消按钮什么事都不做
                                                        builder.create().show();
                                                        break;
                                                    case 21:
                                                        System.exit(0);
                                                        break;
                                                }
                                            }
                                        }

        );
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add("menu");
        return super.onCreateOptionsMenu(menu);
    }

    private SimpleAdapter getMenuAdapter(String[] menuNameArray,
                                         int[] imageResourceArray) {
        ArrayList<HashMap<String, Object>> data = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < menuNameArray.length; i++) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("itemImage", imageResourceArray[i]);
            map.put("itemText", menuNameArray[i]);
            data.add(map);
        }
        SimpleAdapter simperAdapter = new SimpleAdapter(this, data,
                R.layout.menu_item, new String[]{"itemImage", "itemText"},
                new int[]{R.id.item_image, R.id.item_text});
        return simperAdapter;
    }

    private Vector<EditText> ets = new Vector<EditText>();

    private LinearLayout.LayoutParams LP_FF = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
    private LinearLayout.LayoutParams LP_FW = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
    private LinearLayout.LayoutParams LP_WW = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

    private void showModifyDialog(String[] fields, String[] values) {
        ScrollView sv = new ScrollView(this);
        sv.setLayoutParams(LP_FF);

        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);
        sv.addView(layout);

        TextView tv;
        EditText et;
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(400, LayoutParams.WRAP_CONTENT);
        //lp.setMargins(70, 0, 0, 0);

        int count = fields.length;
        ets.clear();
        for (int i = 0; i < count; ++i) {
            tv = new TextView(act);
            tv.setText(fields[i]);
            tv.setTextAppearance(act, android.R.style.TextAppearance_Medium);
            layout.addView(tv);
            et = new EditText(act);
            et.setLayoutParams(lp);
            et.setSingleLine(true);
            et.setTextAppearance(act, android.R.style.TextAppearance_Medium);
            et.setTextColor(0xFF000000);
            if (values != null) et.setText(values[i]);
            layout.addView(et);
            ets.addElement(et);
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(act);
        builder.setView(sv).setTitle("修改属性").setIcon(R.drawable.icon)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        int count = ets.size();
                        String[] values = new String[count];
                        for (int i = 0; i < count; ++i) {
                            values[i] = ets.elementAt(i).getText().toString();
                        }
                        ft.setValues(values);
                        editTool.confirm();
                    }

                })
                .setNegativeButton("取消", new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        editTool.cancel();
                    }
                });
        builder.create().show();
    }

    //地图接口回调
    @Override
    public void onAddFeature(IFeature ft, ILayer layer) {
        this.ft = ft;
        IFeatureLayer flayer = (IFeatureLayer) layer;
        this.showModifyDialog(flayer.getFeatureClass().getFields(), ft.getValues());
    }

    //地图接口回调
    @Override
    public void onDeleteFeature(IFeature ft, ILayer layer) {
        editTool.confirm();    //不提示,直接删除要素
    }

    //地图接口回调
    @Override
    public void onUpdateFeature(IFeature ft, ILayer layer) {
        IMapTool mt = mapView.getMapControl().getCurrentTool();
        if (mt == null) return;
        if (!(mt instanceof EditFeatureTool)) {
            this.ft = ft;
            IFeatureLayer flayer = (IFeatureLayer) layer;
            this.showModifyDialog(flayer.getFeatureClass().getFields(), ft.getValues());
        } else {
            //移动线上的节点之后,这里一起移动点图层上的对应的点要素
            ILayer lyr = mapView.getMapControl().getMap().getLayer("点");
            if (lyr != null && lyr instanceof ShapefileLayer) {
                EditFeatureTool eTool = (EditFeatureTool) mt;
                ShapefileLayer sLayer = (ShapefileLayer) lyr;
                //使用selectFeature函数查询点击处的点要素
                IFeature oldFeature = sLayer.selectFeature(mapView.getMapControl().getDisplay().getDisplayTransformation(), eTool.selector.getX(), eTool.selector.getY(), 10);
                if (oldFeature == null) return;
                IFeature newFeature = oldFeature.clone(true, false);//这里仅仅克隆一个具有相同shape的新要素
                if (eTool.newFeature.getShape() instanceof LineString) {
                    LineString line = (LineString) eTool.newFeature.getShape();
                    IPoint pt = line.getPoint(eTool.nodeIndex);//获取移动之后的节点位置(地图坐标)
                    IPoint newPoint = (IPoint) newFeature.getShape();
                    newPoint.setX(pt.getX());
                    newPoint.setY(pt.getY());//将这个新要素的坐标移动到上述节点位置上
                    sLayer.updateFeature(oldFeature, newFeature, true, false);//更新点要素位置
                }
            }
        }
    }

怎么编辑,选中图斑,导出shp,查询属性等等。

5,权限

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
还有注意你的application一定是这个

 android:name="cn.creable.gridgis.controls.App"
要么你就写一个application继承上面那个。

6,说一下注意事项

如果你的两个界面都是有地图控件,那么销毁界面时候,地图资源记得要释放。不然另外一个地图界面还是一样的数据。

我建议大家下载demo进行运行,然后查看代码,对照接口中文注释,然后看pdf。

大家有没有看过arcgis for android 和超图supmap 的sdk 都是有着版本更新非常大变化。重构幅度很大。

加载shp思路基本都是转换成自已一种格式,进行范围和坐标管理显示。有些是进行R树查询。

其实有个很大难点就是绘制很大的shp文件,怎么做算法查找和显示。

大家对gis这些开发上思路也可以评论一下。





猜你喜欢

转载自blog.csdn.net/qq_16064871/article/details/79119976
今日推荐