Fy.L 的个人博客

自学尚未成才的码农0=0


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 日程表

  • 站点地图

  • 公益404

  • 搜索

ArcGIS Runtime Android查看Shapefile几何类型

发表于 2019-01-10 | 分类于 ArcGIS , ArcGIS Runtime for Android |
字数统计: 104 字 | 阅读时长 ≈ 1分钟

标签 :


【参考链接】
http://zhihu.esrichina.com.cn/question/19622

【问题描述】

调用ShapefileFeatureTable.getGeometryType返回几何类型是Unknown。

【解决办法】:
这一问题和ArcGIS Runtime SDK 100系列中的Loadable异步加载机制有关系,需要在加载完成的回调函数中进行判断

1
2
3
4
5
6
7
8
shapefileFeatureTable = new ShapefileFeatureTable(Environment.getExternalStorageDirectory().getAbsolutePath() + /ArcGIS/shapefile/center.shp);
shapefileFeatureTable.loadAsync();
shapefileFeatureTable.addDoneLoadingListener(new Runnable() {
@Override
public void run() {
System.out.println(shapefileFeatureTable.getGeometryType());
}
});

【转载】ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据编辑

发表于 2019-01-10 | 分类于 ArcGIS , ArcGIS Runtime for Android |
字数统计: 2,062 字 | 阅读时长 ≈ 9分钟

【原文链接:https://www.cnblogs.com/gis-luq/p/5858055.html】


1、前言

在上一篇我们已经实现了离线地理数据库的下载,这一篇我们着重介绍离线数据库的加载与编辑。

由于ArcGIS Runtime SDK for Android 10.2.X版本并没提供要素绘制功能,所以本篇中的要素绘制部分基于之前开源的Drawtools3.0工具实现。

本DEMO主要实现了:离线地理数据库加载、要素样式模板加载,要素新建、要素选择并开启编辑状态、要素删除等操作。由于内容较多涉及编辑部分仅详细介绍对Geodatabase的要素添加、要素删除、要素更新部分,其余请自行查阅源代码。

离线地理数据库编辑

转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858055.html

2、离线要素编辑实现过程

2.1、加载本地离线要素

ArcGIS Runtime SDK for Android中提供了具体的Geodatabase类和FeatureLayer图层来加载.geodatabase文件,常用的类包括Geodatabase、GeodatabaseFeatureTable、GeodatabaseFeature、GeodatabaseFeatureServiceTable等,分别用来打开geodatabase数据文件、获取要素图层、获取图层中的具体要素,以及获取在线的要素服务。具体来讲,加载.geodatabase文件的步骤有如下几步:

  1. 实例化一个Geodatabase对象,这个类有两个构造函数,都需要指定本地数据库的存储路径;
  2. 创建一个GeodatabaseFeatureTable对象实例,用来获取需要的图层;
  3. 创建一个FeatureLayer来存储获取的图层,并将获取的图层加载到地图中;
  4. 调用dispose()方式释放资源。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /** * 读取Geodatabase中离线地图信息
    * @param geodatabsePath 离线Geodatabase文件路径 */
    private void addFeatureLayer(String geodatabsePath) {
    Geodatabase localGdb = null;
    try {
    localGdb = new Geodatabase(geodatabsePath);
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    }
    layerList = new ArrayList<>(); // 添加FeatureLayer到MapView中
    if (localGdb != null) {
    for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseTables()) {
    if (gdbFeatureTable.hasGeometry()){
    FeatureLayer layer = new FeatureLayer(gdbFeatureTable);
    mMapView.addLayer(layer);
    }
    }
    }
    }

2.2、加载本地要素样式模板

点

线

面

绘制要素时往往会需要知道待绘制要素的图层名称以及要素的符号化样式,这里我们以geodatabse中的FeatureLayer为例演示要素样式模板获取流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** * 添加要素绘制样式模板
* 获取图层要素模板并添加到featureTempleteView
* @param layer */
private void addFeatureTemplate(FeatureLayer layer) {
List<FeatureTemplate> featureTemp = ((GeodatabaseFeatureTable) layer.getFeatureTable()).getFeatureTemplates();
for (FeatureTemplate featureTemplate : featureTemp) {
GeodatabaseFeature g = null;
try {
g = ((GeodatabaseFeatureTable) layer.getFeatureTable()).createFeatureWithTemplate(featureTemplate, null);
Renderer renderer = layer.getRenderer();
Symbol symbol = renderer.getSymbol(g); float scale = context.getResources().getDisplayMetrics().density; int widthInPixels = (int) (35 * scale + 0.5f);
Bitmap bitmap = SymbolHelper.getLegendImage(symbol, widthInPixels, widthInPixels); //将要素样式模板赋值给imgButton
ImageButton imageButton = new ImageButton(context);
imageButton.setImageBitmap(bitmap);
imageButton.setTag(layer);//保存当前待编辑图层
((LinearLayout)featureTempleteView).addView(imageButton);//添加到要素样式模板列表
imageButton.setOnClickListener(new ImageButtonOnClickListener());
} catch (TableException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "Error:" + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
}
}

2.2 编辑本地离线要素

要素编辑最核心的是FeatureTable中的增删改方法,通过这些方法可以实现本地数据库中要素编辑操作。

FeatureTable中的常用方法如下:

  • addFeature):增加本地要素
  • addFeatures):一次添加多个要素到离线数据库中
  • deleteFeature):删除本地要素
  • deleteFeatures):删除多个本地要素
  • queryFeatures):查询本地要素
  • updateFeature):更新要素到本地
  • updateFeatures):更新多个要素到本地

2.2.1 要素添加

1
2
3
4
5
6
7
8
private FeatureLayer selectFeatureLayer;//当前选中图层 
private Graphic selectGraphic = null;//待添加要素(零时图层中获取)
GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable();
GeodatabaseFeature gdbFeature = new GeodatabaseFeature(null, selectGraphic.getGeometry(), geodatabaseFeatureTable); long fid = geodatabaseFeatureTable.addFeature(gdbFeature);// 添加要素
Log.d(TAG,"要素添加成功,Feature ID:"+fid);
} catch (TableException e) {
e.printStackTrace();
}

2.2.2 要素删除

1
2
3
4
5
6
7
8
9
10
private FeatureLayer selectFeatureLayer;//当前选中图层
private Feature selectFeature = null;//当前选中要素
GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable();
try{
if (selectFeature!=null){
eodatabaseFeatureTable.deleteFeature(selectFeature.getId());//删除要素
}
} catch (TableException e) {
e.printStackTrace();
}

2.2.3 要素矢量信息更新

1
2
3
4
5
6
7
8
9
private FeatureLayer selectFeatureLayer;//当前选中图层 private Feature selectFeature = null;//当前选中要素
private Graphic selectGraphic = null;//待更新要素(零时图层中获取)
try {
GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable();
geodatabaseFeatureTable.updateFeature(selectFeature.getId(),selectGraphic.getGeometry());//更新要素
Log.d(TAG,"要素更新成功");
} catch (TableException e) {
e.printStackTrace();
}

扩展说明:如何选中要素,以及如何处理具有压盖关系的要素选择问题?

针对这两个问题我们一并处理,首先扩展MapOnTouchListener类,实现长按出现放大镜,并选中要素。选中要素时我们采用遍历当前所有图层的方式,找出每个图层中第一个被选中的要素,然后弹窗提示供用户选择。

1
2
3
4
5
6
//全局定义信息
private List<FeatureLayer> layerList;//矢量图层列表
private GraphicsLayer graphicsLayer = null;//零时图层
private FeatureLayer selectFeatureLayer;//当前选中图层
private Graphic selectGraphic = null;//当前选中要素(零时图层)
private Feature selectFeature = null;//当前选中要素

要素选中扩展事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/** * 地图窗口默认Touch事件
* 支持长按放大镜选种要素 */
public class MapSelectFeatureOnTouchListener extends MapOnTouchListener{

public MapSelectFeatureOnTouchListener(Context context, MapView view) {
super(context, view);
}

@Override public boolean onLongPressUp(MotionEvent point) {
handleTap(point); //长按放大镜选择事件
super.onLongPressUp(point); return true;
}

@Override public boolean onSingleTap(final MotionEvent e) { //单击响应事件
return true;
}

/** * 获取当前选中要素
* @param point */
private void handleTap(MotionEvent point) {
MotionEvent screePoint = point; //选中图层信息
final List<SelectFeatureInfo> selectFeatureInfoList = new ArrayList<>(); //记录当前选中要素信息,涉及多个图层情况
for (int i=0;i<layerList.size();i++){
FeatureLayer featureLayer = layerList.get(i);
featureLayer.setSelectionColor(Color.YELLOW);
featureLayer.setSelectionColorWidth(10); long[] selids = featureLayer.getFeatureIDs(screePoint.getX(), screePoint.getY(), 1); if (selids.length >= 1) {
SelectFeatureInfo selectFeatureInfo = new SelectFeatureInfo();
selectFeatureInfo.featureLayer = featureLayer;
selectFeatureInfo.selectFeatureID = selids[0];
selectFeatureInfoList.add(selectFeatureInfo);
}
}
//根据待选图层确定是否弹窗选择
if(selectFeatureInfoList.size()>1){ //当前选中要素大于1个图层
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("请确认选择哪个图层要素?"); //指定下拉列表的显示数据
final String[] layerNamelist = getSelectFeatureInfoListName(selectFeatureInfoList); //设置一个下拉的列表选择项
builder.setItems(layerNamelist, new DialogInterface.OnClickListener()
{
@Override public void onClick(DialogInterface dialog, int which)
{
Toast.makeText(MainActivity.this, "选择的图层为:" + layerNamelist[which], Toast.LENGTH_SHORT).show();
SelectFeatureInfo selectFeaInfo = getFeatureLayerbyName(selectFeatureInfoList,layerNamelist[which]);
setSelectFeature(selectFeaInfo);//根据选中图层信息选中当前要素
}
});
builder.show();
}else if(selectFeatureInfoList.size()==1) {
SelectFeatureInfo selectFeaInfo = selectFeatureInfoList.get(0);
setSelectFeature(selectFeaInfo);//根据选中图层信息选中当前要素
}

}

/** * 设置选中图层的要素选中信息
* @param selectFeaInfo 待选图层信息 */
private void setSelectFeature(SelectFeatureInfo selectFeaInfo) {
clearFeatureSelection();//设置选中状态前,清空已选择要素
selectFeaInfo.featureLayer.selectFeature(selectFeaInfo.selectFeatureID);
selectFeatureLayer = selectFeaInfo.featureLayer;
selectFeature = selectFeatureLayer.getFeature(selectFeaInfo.selectFeatureID); switch (selectFeature.getGeometry().getType()){
case POINT: case MULTIPOINT:
selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.markerSymbol, null);
break;
case LINE: case POLYLINE:
selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.mLineSymbol,null);
break;
case ENVELOPE:
case POLYGON:
selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.mFillSymbol, null);
break;
default:
break;
}
}

/** * 通过图层名称获取要素
* @param name 图层名称
* @return 选中图层信息 */
private SelectFeatureInfo getFeatureLayerbyName(List<SelectFeatureInfo> selectFeatureInfoList,String name){
SelectFeatureInfo selectinfo= null;
for (int i=0;i<selectFeatureInfoList.size();i++){
FeatureLayer tmplayer = selectFeatureInfoList.get(i).featureLayer;
if (tmplayer.getName().equals(name)){
selectinfo = selectFeatureInfoList.get(i);//选中图层信息
}
}
return selectinfo;
}

/** * 获取待选择要素列表名称
* @param selectFeatureInfoList 待选中要素列表信息
* @return
*/
private String[] getSelectFeatureInfoListName(List<SelectFeatureInfo> selectFeatureInfoList) {
List<String> lsname = new ArrayList<>(); for (int i=0;i<selectFeatureInfoList.size();i++){
lsname.add(selectFeatureInfoList.get(i).featureLayer.getName());
} return lsname.toArray(new String[lsname.size()]);
}

/** * 记录当前选中要素信息 */
public class SelectFeatureInfo{ public FeatureLayer featureLayer ;//当前选中要素
public long selectFeatureID ;//当前选中要素ID
}
}

3、完整代码

完整代码不定期更新,具体请查阅DEMOt源代码,托管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEdit

4、运行后编辑结果(以备同步测试使用)

编辑结果

转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858055.html

文章若无特殊说明均为原创,原创作品,允许转载,转载时请务必以超链接形式标明文章出处、作者信息和本声明。
博客:http://www.cnblogs.com/gis-luq​ 作者:gis-luq 邮箱:luqiang.gis@foxmail.com

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据下载

发表于 2019-01-10 | 分类于 ArcGIS , ArcGIS Runtime for Android |
字数统计: 1,848 字 | 阅读时长 ≈ 9分钟

【原文链接:http://www.cnblogs.com/gis-luq/p/5858048.html 】


1、前言

1.1、环境准备:

  • ArcGIS for Desktop 10.4.1(10.2.1以上版本即可)
  • ArcGIS for Server 10.4.1 (10.2.1以上版本即可)
  • PostgreSQL、Microsoft SQL Server、或 Oracle 设置企业级地理数据库。

1.2、发布具有同步能力的FeatureService服务

  过程参考 数据制作篇:发布具有同步能力的FeatureService服务 一文。

image

转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858048.html

2、demo实现过程

ArcGIS Runtime SDK 配置实现过程略:具体请参考:

基于Android Studio构建ArcGIS Android开发环境

基于Android Studio构建ArcGIS Android开发环境(离线部署)

2.1、Demo UI实现

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.downgdb.MainActivity">

<!-- MapView -->
<com.esri.android.map.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
mapoptions.MapType="Topo"
mapoptions.ZoomLevel="5"
mapoptions.center="28.671298, 104.066404" />

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/linearLayout"
android:background="@color/primary_material_light">

<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/editTextGDBUrl"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_weight="1"
android:text="http://192.168.1.212:6080/arcgis/rest/services/testdata/FeatureServer" android:inputType="textUri" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="数据下载"
android:id="@+id/btnDownGDB" />
</LinearLayout>

</RelativeLayout>

2.2、在Android清单文件AndroidManifest.xml中增加网络及存储访问权限

1
2
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2.3、实现离线地理数据库下载逻辑

基本思路:

  1. 设置.geodatabase文件存储路径
  2. 根据FeatureService服务获取FeatureServiceInfo服务参数信息
  3. 根据FeatureServiceInfo信息创建离线地理数据库文件、
  4. 从已经下载的本地Geodatabase文件中加载矢量数据

下载数据的核心功能类说明:

  • GeodatabaseSyncTask类,实现下载同步功能

  • GenerateGeodatabaseParameters,下载数据时所需的参数对象,该类构造函数一共有7个根据需要选择:

image

本次示例代码主要用到以下三个参数:

    • featureServerInfo 服务参数信息
    • geodatabaseExtent 地图下载区域范围
    • geodatabaseSpatialReference 地图空间参考
  • CallbackListener,完成GDB数据库下载的回调函数类,在该回调中我们只可以执行一些操作,如示例里在回调中删除了在线的服务图层,加载离线的数据图层到地图上进行显示。通过Geodatabase本地数据库可以获取要素图层列表List<GdbFeatureTable>对象,通过newFeatureLayer(gdbFeatureTable)来创建一个离线要素图层进行要素显示。

  • GeodatabaseStatusCallback,本地数据库回调状态类,在数据下载过程中会有很多状态改变,各种状态改变时都会走这个类的回调函数。
  • GeodatabaseTask.generateGeodatabase,通过该方法生成离线数据库和相应的要素表,方法需要传递上面介绍的三个参数和一个数据库存储的路径。

完整代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.example.downgdb; 
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import com.esri.android.map.FeatureLayer;
import com.esri.android.map.MapView;
import com.esri.core.ags.FeatureServiceInfo;
import com.esri.core.geodatabase.Geodatabase;
import com.esri.core.geodatabase.GeodatabaseFeatureTable;
import com.esri.core.map.CallbackListener;
import com.esri.core.tasks.geodatabase.GenerateGeodatabaseParameters;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusCallback;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusInfo;
import com.esri.core.tasks.geodatabase.GeodatabaseSyncTask;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
protected static final String TAG = "downGDB";
private Context context; private MapView mMapView;//地图容器

private EditText editTextDownGDBUrl;//GDB地址
private Button btnDownGDB;//下载GDB

private static String onlineFeatureLayerUrl;//在线FeatureLayer地址
private static String localGdbFilePath;//离线GDB地址

private GeodatabaseSyncTask gdbSyncTask;//离线地理数据库下载Task
private ProgressDialog mProgressDialog;//状态框

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

context = this; // 默认软键盘不弹出
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
this.mMapView = (MapView)findViewById(R.id.map);
this.editTextDownGDBUrl = (EditText)findViewById(R.id.editTextGDBUrl); //获取并设置在线服务地址
this.onlineFeatureLayerUrl = this.editTextDownGDBUrl.getText().toString();

mProgressDialog = new ProgressDialog(context); //设置点击进度对话框外的区域对话框不消失
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setTitle("正在创建离线地理数据库副本"); //绑定按钮设置下载事件
btnDownGDB = (Button)this.findViewById(R.id.btnDownGDB);
btnDownGDB.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
downloadData(onlineFeatureLayerUrl);//下载离线数据
}
});

}

/**
* Geodatabase文件存储路径
*/
static String createGeodatabaseFilePath() {
return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "/RuntimeOfflineEdit"
+ File.separator + "demo.geodatabase";
}

/**
* 下载离线地理数据库
* @param url FeatureService服务地址
* 例如:http://192.168.1.212:6080/arcgis/rest/services/testdata/FeatureServer
* 支持ArcGIS for Server 10.2.1以上版本,必须开启FeatureServer要素同步功能 */
private void downloadData(String url) {
Log.i(TAG, "Create GeoDatabase"); // create a dialog to update user on progress
mProgressDialog.show();

gdbSyncTask = new GeodatabaseSyncTask(url, null);
gdbSyncTask.fetchFeatureServiceInfo(new CallbackListener<FeatureServiceInfo>() {
@Override public void onError(Throwable arg0) {
Log.e(TAG, "获取FeatureServiceInfo失败");
}

@Override public void onCallback(FeatureServiceInfo fsInfo) { if (fsInfo.isSyncEnabled()) {
createGeodatabase(fsInfo);
}
}
});
}

/**
* 根据FeatureServiceInfo信息创建离线地理数据库文件
* @param featureServerInfo 服务参数信息 */
private void createGeodatabase(FeatureServiceInfo featureServerInfo) { // 生成一个geodatabase设置参数
GenerateGeodatabaseParameters params = new GenerateGeodatabaseParameters(
featureServerInfo, mMapView.getMaxExtent(), mMapView.getSpatialReference()); // 下载结果回调函数
CallbackListener<String> gdbResponseCallback = new CallbackListener<String>() {
@Override public void onError(final Throwable e) {
Log.e(TAG, "创建geodatabase失败");
mProgressDialog.dismiss();
}

@Override public void onCallback(String path) {
Log.i(TAG, "Geodatabase 路径: " + path);
mProgressDialog.dismiss();
loadGeodatabase(path);
}
}; // 下载状态回调函数
GeodatabaseStatusCallback statusCallback = new GeodatabaseStatusCallback() {
@Override public void statusUpdated(final GeodatabaseStatusInfo status) {
final String progress = status.getStatus().toString(); //在UI线程更新下载状态
((Activity)context).runOnUiThread(new Runnable(){
@Override public void run() {
mProgressDialog.setMessage("数据下载中,请稍后……");
}
});

}
}; //设置离线地理数据库存储路径
localGdbFilePath = createGeodatabaseFilePath(); //执行下载Geodatabase数据库
gdbSyncTask.generateGeodatabase(params, localGdbFilePath, false, statusCallback, gdbResponseCallback);
}

/** * 加载离线地理数据库
* @param path .geodatabse文件路径
*/
private void loadGeodatabase(String path) { // 创建一个geodatabase数据库
Geodatabase localGdb = null; try {
localGdb = new Geodatabase(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
} // 添加FeatureLayer到MapView中
if (localGdb != null) {
for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseTables()) {
if (gdbFeatureTable.hasGeometry()){
mMapView.addLayer(new FeatureLayer(gdbFeatureTable));
}
}
}
}
}

3、Demo运行结果

image

源代码托管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEdit

4、参考资料

https://developers.arcgis.com/android/api-reference/reference/com/esri/core/tasks/geodatabase/package-summary.html

http://blog.csdn.net/arcgis_all/article/details/20442663

相关内容列表

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:概述

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据下载

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据编辑

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据同步

《ArcGIS Runtime SDK for Android开发笔记》——数据制作篇:发布具有同步能力的FeatureService服务

文章若无特殊说明均为原创,原创作品,允许转载,转载时请务必以超链接形式标明文章出处、作者信息和本声明。
博客:http://www.cnblogs.com/gis-luq​ 作者:gis-luq 邮箱:luqiang.gis@foxmail.com

在一个项目中同时使用ArcGIS Runtime 和 百度定位SDK

发表于 2019-01-10 | 分类于 ArcGIS , ArcGIS Runtime for Android |
字数统计: 1,180 字 | 阅读时长 ≈ 4分钟

【参考链接:https://zhidao.baidu.com/question/2267129986490031988.html】
【本文尚未修改编辑,版本号还是老版本】


两个SDK都是将其API库封装成so动态链接库供上层应用(Java)调用,但两者在具体实现上存在差异,也是这个差异导致将两个SDK集成到一个应用中时容易产生强退的bug,这个问题也曾很大的困扰了我一天,特此分享给大家。

  ☆ 先看看百度地图 for Android SDK的动态库调用方法:

  第一步:在工程里新建libs文件夹,将开发包里的baidumapapi_v2_1_2.jar拷贝到libs根目录下,将libapp_BaiduMapApplib_v2_1_2.so和libvi_voslib.so 拷贝到libs\armeabi目录下(官网demo里已有这三个文件,如果要集成到自己的工程里,就需要自己添加),拷贝完成后的工程目录如下图所示;

  注:liblocSDK3.so和locSDK_3.1.jar为百度定位SDK所使用资源,开发者可根据实际需求自行添加。

添加Jar包

  第二步:在工程属性->Java Build Path->Libraries中选择“Add External JARs”,选定baidumapapi_v2_1_2.jar,确定后返回。

  通过以上两步操作后,您就可以正常使用百度地图SDK为您提供的全部功能了。

  ☆ 再看看ArcGIS for Android SDK的动态库调用方法

  其是通过在Eclipse集成开发环境上安装ArcGIS插件来实现的,具体如何安装就不赘述了。当 ArcGIS开发插件安装完成后,在新建工程的选项中就可以看到【ArcGIS Project for Android】和【ArcGIS Samples for Android】的菜单,ArcGIS Android API的开发环境就顺利配置完成了。

  然后你可以New –> Project –>ArcGIS Project for Android来新建一个带其动态链接库的Android应用程序。例如创建一个test工程,创建成功后如下图所示。本例采用最新的ArcGIS for Android SDK 10.1。

ArcGIS Runtime 10.1

  小结:以上两种方法,从用户便捷性上来说,ArcGIS 更加“智能”一些,将动态链接库添加的工作,直接已经集成到new project里面,对于初学者来说,可以完全忽略这些细节而直接进入关键开发工作;百度地图的SDK相对来说,更加灵活一些,给用户更大的空间。

  但也就是这两种方式的差异导致了当两个SDK结合到一个程序里的时候就容易出错。细心的朋友应该可以发现一个问题,百度地图SDK里的动态链接库只有一个armeabi文件夹,但是ArcGIS SDK却有两个文件夹,armeabi和armeabi-v7a,其中均有一个libruntimecore_java.so库文件。

  这两个文件夹是何用意呢?armeabi和armeabi-v7a是表示cpu的类型,不同的cpu的特性不一样,armeabi就是针对普通的或旧的arm cpu,armeabi-v7a是针对有浮点运算或高级扩展功能的arm cpu。简单来说,Android为了适应五花八门各式各样的智能终端硬件环境,采用了不同的配置对应不同文件夹的调用模式,好比大家熟悉的不同屏幕dpi会调用不同的图片文件夹,如下图。

适配

  那么关键的来了,当我们严格按照两个SDK添加链接库后,百度地图三个so库文件就存放在armeabi文件夹下,而armeabi-v7a文件夹下并没有百度地图相应的so库,但ArcGIS却在两个文件夹下都有相应的so库,这里不得不说,Esri作为GIS、地图领域的世界领头羊,考虑的还是比较细。

  然后编译程序时,Eclipse会在两个文件夹里搜索相应的库文件,而只会根据Android手机的具体情况拷贝相应文件夹下的库文件。当今绝大多数的手机已经具备了针对有浮点运算或高级扩展功能的arm cpu,所以在手机根目录下/data/data/(program_name)/lib下只会拷贝armeabi-v7a文件夹下的库文件,而此时并不会有百度地图的so库文件。从而会导致百度地图SDK程序直接崩溃,并报出java.lang.ExceptionInInitializerError错误。

  明白了原理,解决办法就十分简单了,将armeabi文件夹下百度地图的so库文件拷贝到armeabi-v7a文件夹下,如下图:

拷贝文件

  重新clean一下project,重新编译后程序就可以正常调用百度地图和ArcGIS两个SDK库了。

注:这里由于我是直接用的Jcenter仓库中的ArcGIS 10.2.9库,只有三个文件夹,而目前百度定位SDK已经适配了所有类型处理器,所以我的操作是删除百度地图中多出来的几个文件夹。

git pull 如何强制覆盖本地文件

发表于 2019-01-10 | 分类于 Git |
字数统计: 1,046 字 | 阅读时长 ≈ 4分钟

原文链接:
https://vimsky.com/article/3679.html

##【需求】
在开发中使用Git的过程中,有时候会有一种需求,要从服务器拉取最新的状态,而本地进行了无关紧要的修改,这时候如果使用git pull命令,会提示本地有未缓存的修改。这时候就需要强制覆盖本地的改变。

阅读全文 »

Git随笔

发表于 2019-01-10 | 分类于 Git |
字数统计: 31 字 | 阅读时长 ≈ 1分钟

##1.推送本地分支到远程仓库

1
git push

如果远程分支不存在

1
git push --set-upstream origin [branch_name]

使用Arduino IDE开发ESP8266模块应用

发表于 2019-01-10 | 分类于 Arduino |
字数统计: 127 字 | 阅读时长 ≈ 1分钟

##一、添加网址
打开Arduino IDE,在文件->首选项菜单中的附加开发板管理器网址中填写如下网址:

1
http://arduino.esp8266.com/stable/package_esp8266com_index.json

附加开发板管理器网址

##二、下载开发板定义
打开工具->开发板->开发板管理器中输入ESP8266,在结果中选择最新版本,并点击安装。
下载开发板定义

##三、选择开发板
最后在工具->开发板根据自己的需求选择对应的型号即可。
我个人需要用到WeMos D1 R1开发板。
WeMos D1 R1

ArcGIS打开后一片空白

发表于 2019-01-10 | 分类于 ArcGIS |
字数统计: 130 字 | 阅读时长 ≈ 1分钟

##问题
最近用到ArcGIS10.2版本。把电脑上的10.1版本卸载了之后,重新安装10.2.2版本,打开之后却是一片空白,如下图:
ArcGIS 10.2

##解决
打开资源管理器,在地址栏中输入:

1
%USERPROFILE%\Application Data\ESRI\Desktop10.2\ArcMap\Templates

如果提示Application Data目录没有权限,参照【https://www.jianshu.com/p/24062f791399】获取所有权,然后再次进入上述目录,找到其中的`Normal.mxt`文件,将其删除。然后重新打开`ArcMap`就可以了。

ArcObjects开发初探

发表于 2019-01-10 | 分类于 ArcGIS |
字数统计: 339 字 | 阅读时长 ≈ 2分钟

最近项目中需要用到ArcGIS二次开发,由于本人并不是地理信息专业科班出身,所以使用过程中遇到很多问题不知道怎么去解决,百度良久,在此记录一番!
本文随时更新!

##一、初始化许可
ArcObjects是ArcGIS的底层API,基于COM技术搭建,所以能够自然地支持C++,VB,.Net在内的多种语言。然而也因为是基于COM的,所以它的API很是难用(相比.Net framework那样的)。
我的系统是Windows 10 专业版 64位+VS 2015+ArcGIS 10.2,考虑到64位的开发环境和运行环境,首先需要在项目中设置平台为x86。
设置项目目标平台为x86

在调用其他ArcObjects API之前,首先得初始化许可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using ESRI.ArcGIS;
using ESRI.ArcGIS.esriSystem;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace 数据处理
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//绑定Runtime
if (!RuntimeManager.Bind(ProductCode.EngineOrDesktop))
{
MessageBox.Show("不能绑定ArcGIS runtime,应用程序即将关闭.");
return;
}
// 初始化AO许可
var aoi = new AoInitialize();
var s = aoi.Initialize(
esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB);

if (s == esriLicenseStatus.esriLicenseUnavailable)
throw new NotSupportedException("请求的许可不可用");

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FrmMain());
}
}
}

Windows ZIP版MySQL安装方法

发表于 2019-01-10 | 分类于 MySQL |
字数统计: 359 字 | 阅读时长 ≈ 1分钟

##【下载地址】
https://dev.mysql.com/downloads/mysql/
直接下载地址:https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.13-winx64.zip
我用的社区免费版。

##1.解压
下载完成后解压缩,我的解压到了D:\Program Files\mysql-8.0.13-winx64目录下。

##2.安装

###2.1 初始化
以管理员身份运行cmd,转到MySQL目录下的bin文件夹下:

1
cd D:\Program Files\mysql-8.0.13-winx64\bin

然后执行初始化命令:

1
mysqld --initialize

执行这条命令之后,在data目录会生成一系列文件,如图:
data目录

###2.2 安装
执行如下命令进行安装:

1
mysqld -install

然后,启动服务:

1
net start mysql

如果顺利,会提示:

1
2
MySQL 服务正在启动...
MySQL 服务已经启动成功。

##3.登陆
我用的是MySQL Workbench软件登陆的。

打开软件,选择Database -> Connect to Database...:
MySQL Workbench

连接选择Local instance MySQL,其他默认不变。
连接数据库

关于密码
新版本的MySQL在第二步安装启动服务时,会生成一个默认初始密码,这个密码存储在data目录下的`*.err**文件夹中,用记事本打开此文件,找到A temporary password is generated for root@localhost:… …`这一行,后面即为默认临时密码。
临时密码

将上述方法得到的密码填写到对话框的Store in Vault对话框中:
输入密码
然后点击OK,第一次登陆会提示修改密码,按照提示操作修改即可。

12…4
Fy.L

Fy.L

你若赐我一段浮华,我便许你满世繁花

38 日志
11 分类
36 标签
RSS
GitHub
© 2019 Fy.L
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4